--- /dev/null
- : (`int`) The maximum amount of system memory, in gigabytes, that Hugo can use while rendering your site. Default is 25% of total system memory. Note that The `HUGO_MEMORYLIMIT` is a “best effort” setting. Don't expect Hugo to build a million pages with only 1 GB memory. You can get more information about how this behaves during the build by building with `hugo --logLevel info` and look for the `dynacache` label.
+---
+title: Introduction
+description: Configure your site using files, directories, and environment variables.
+categories: []
+keywords: []
+weight: 10
+---
+
+## Sensible defaults
+
+Hugo offers many configuration options, but its defaults are often sufficient. A new site requires only these settings:
+
+{{< code-toggle file=hugo >}}
+baseURL = 'https://example.org/'
+languageCode = 'en-us'
+title = 'My New Hugo Site'
+{{< /code-toggle >}}
+
+Only define settings that deviate from the defaults. A smaller configuration file is easier to read, understand, and debug. Keep your configuration concise.
+
+> [!note]
+> The best configuration file is a short configuration file.
+
+## Configuration file
+
+Create a site configuration file in the root of your project directory, naming it `hugo.toml`, `hugo.yaml`, or `hugo.json`, with that order of precedence.
+
+```text
+my-project/
+└── hugo.toml
+```
+
+> [!note]
+> For versions v0.109.0 and earlier, the site configuration file was named `config`. While you can still use this name, it's recommended to switch to the newer naming convention, `hugo`.
+
+A simple example:
+
+{{< code-toggle file=hugo >}}
+baseURL = 'https://example.org/'
+languageCode = 'en-us'
+title = 'ABC Widgets, Inc.'
+[params]
+subtitle = 'The Best Widgets on Earth'
+[params.contact]
+email = 'info@example.org'
+phone = '+1 202-555-1212'
+{{< /code-toggle >}}
+
+To use a different configuration file when building your site, use the `--config` flag:
+
+```sh
+hugo --config other.toml
+```
+
+Combine two or more configuration files, with left-to-right precedence:
+
+```sh
+hugo --config a.toml,b.yaml,c.json
+```
+
+> [!note]
+> See the specifications for each file format: [TOML], [YAML], and [JSON].
+
+## Configuration directory
+
+Instead of a single site configuration file, split your configuration by [environment](g), root configuration key, and language. For example:
+
+```text
+my-project/
+└── config/
+ ├── _default/
+ │ ├── hugo.toml
+ │ ├── menus.en.toml
+ │ ├── menus.de.toml
+ │ └── params.toml
+ └── production/
+ └── params.toml
+```
+
+The root configuration keys are {{< root-configuration-keys >}}.
+
+### Omit the root key
+
+When splitting the configuration by root key, omit the root key in the component file. For example, these are equivalent:
+
+{{< code-toggle file=config/_default/hugo >}}
+[params]
+foo = 'bar'
+{{< /code-toggle >}}
+
+{{< code-toggle file=config/_default/params >}}
+foo = 'bar'
+{{< /code-toggle >}}
+
+### Recursive parsing
+
+Hugo parses the `config` directory recursively, allowing you to organize the files into subdirectories. For example:
+
+```text
+my-project/
+└── config/
+ └── _default/
+ ├── navigation/
+ │ ├── menus.de.toml
+ │ └── menus.en.toml
+ └── hugo.toml
+```
+
+### Example
+
+```text
+my-project/
+└── config/
+ ├── _default/
+ │ ├── hugo.toml
+ │ ├── menus.en.toml
+ │ ├── menus.de.toml
+ │ └── params.toml
+ ├── production/
+ │ ├── hugo.toml
+ │ └── params.toml
+ └── staging/
+ ├── hugo.toml
+ └── params.toml
+```
+
+Considering the structure above, when running `hugo --environment staging`, Hugo will use every setting from `config/_default` and merge `staging`'s on top of those.
+
+Let's take an example to understand this better. Let's say you are using Google Analytics for your website. This requires you to specify a [Google tag ID] in your site configuration:
+
+{{< code-toggle file=hugo >}}
+[services.googleAnalytics]
+ID = 'G-XXXXXXXXX'
+{{< /code-toggle >}}
+
+Now consider the following scenario:
+
+1. You don't want to load the analytics code when running `hugo server`.
+1. You want to use different Google tag IDs for your production and staging environments. For example:
+ - `G-PPPPPPPPP` for production
+ - `G-SSSSSSSSS` for staging
+
+To satisfy these requirements, configure your site as follows:
+
+1. `config/_default/hugo.toml`
+ - Exclude the `services.googleAnalytics` section. This will prevent loading of the analytics code when you run `hugo server`.
+ - By default, Hugo sets its `environment` to `development` when running `hugo server`. In the absence of a `config/development` directory, Hugo uses the `config/_default` directory.
+1. `config/production/hugo.toml`
+ - Include this section only:
+
+ {{< code-toggle file=hugo >}}
+ [services.googleAnalytics]
+ ID = 'G-PPPPPPPPP'
+ {{< /code-toggle >}}
+
+ - You do not need to include other parameters in this file. Include only those parameters that are specific to your production environment. Hugo will merge these parameters with the default configuration.
+ - By default, Hugo sets its `environment` to `production` when running `hugo`. The analytics code will use the `G-PPPPPPPPP` tag ID.
+
+1. `config/staging/hugo.toml`
+
+ - Include this section only:
+
+ {{< code-toggle file=hugo >}}
+ [services.googleAnalytics]
+ ID = 'G-SSSSSSSSS'
+ {{< /code-toggle >}}
+
+ - You do not need to include other parameters in this file. Include only those parameters that are specific to your staging environment. Hugo will merge these parameters with the default configuration.
+ - To build your staging site, run `hugo --environment staging`. The analytics code will use the `G-SSSSSSSSS` tag ID.
+
+## Merge configuration settings
+
+Hugo merges configuration settings from themes and modules, prioritizing the project's own settings. Given this simplified project structure with two themes:
+
+```text
+project/
+├── themes/
+│ ├── theme-a/
+│ │ └── hugo.toml
+│ └── theme-b/
+│ └── hugo.toml
+└── hugo.toml
+```
+
+and this project-level configuration:
+
+{{< code-toggle file=hugo >}}
+baseURL = 'https://example.org/'
+languageCode = 'en-us'
+title = 'My New Hugo Site'
+theme = ['theme-a','theme-b']
+{{< /code-toggle >}}
+
+Hugo merges settings in this order:
+
+1. Project configuration (`hugo.toml` in the project root)
+1. `theme-a` configuration
+1. `theme-b` configuration
+
+The `_merge` setting within each top-level configuration key controls _which_ settings are merged and _how_ they are merged.
+
+The value for `_merge` can be one of:
+
+none
+: No merge.
+
+shallow
+: Only add values for new keys.
+
+deep
+: Add values for new keys, merge existing.
+
+Note that you don't need to be so verbose as in the default setup below; a `_merge` value higher up will be inherited if not set.
+
+{{< code-toggle file=hugo dataKey="config_helpers.mergeStrategy" skipHeader=true />}}
+
+## Environment variables
+
+You can also configure settings using operating system environment variables:
+
+```sh
+export HUGO_BASEURL=https://example.org/
+export HUGO_ENABLEGITINFO=true
+export HUGO_ENVIRONMENT=staging
+hugo
+```
+
+The above sets the [`baseURL`], [`enableGitInfo`], and [`environment`] configuration options and then builds your site.
+
+> [!note]
+> An environment variable takes precedence over the values set in the configuration file. This means that if you set a configuration value with both an environment variable and in the configuration file, the value in the environment variable will be used.
+
+Environment variables simplify configuration for [CI/CD](g) deployments like GitHub Pages, GitLab Pages, and Netlify by allowing you to set values directly within their respective configuration and workflow files.
+
+> [!note]
+> Environment variable names must be prefixed with `HUGO_`.
+>
+> To set custom site parameters, prefix the name with `HUGO_PARAMS_`.
+
+For snake_case variable names, the standard `HUGO_` prefix won't work. Hugo infers the delimiter from the first character following `HUGO`. This allows for variations like `HUGOxPARAMSxAPI_KEY=abcdefgh` using any [permitted delimiter].
+
+In addition to configuring standard settings, environment variables may be used to override default values for certain internal settings:
+
+DART_SASS_BINARY
+: (`string`) The absolute path to the Dart Sass executable. By default, Hugo searches for the executable in each of the paths in the `PATH` environment variable.
+
+HUGO_FILE_LOG_FORMAT
+: (`string`) A format string for the file path, line number, and column number displayed when reporting errors, or when calling the `Position` method from a shortcode or Markdown render hook. Valid tokens are `:file`, `:line`, and `:col`. Default is `:file::line::col`.
+
+HUGO_MEMORYLIMIT
+: {{< new-in 0.123.0 />}}
++: (`int`) The maximum amount of system memory, in gigabytes, that Hugo can use while rendering your site. Default is 25% of total system memory. Note that `HUGO_MEMORYLIMIT` is a "best effort" setting. Don't expect Hugo to build a million pages with only 1 GB of memory. You can get more information about how this behaves during the build by building with `hugo --logLevel info` and look for the `dynacache` label.
+
+HUGO_NUMWORKERMULTIPLIER
+: (`int`) The number of workers used in parallel processing. Default is the number of logical CPUs.
+
+## Current configuration
+
+Display the complete site configuration with:
+
+```sh
+hugo config
+```
+
+Display a specific configuration setting with:
+
+```sh
+hugo config | grep [key]
+```
+
+Display the configured file mounts with:
+
+```sh
+hugo config mounts
+```
+
+[`baseURL`]: /configuration/all#baseurl
+[`enableGitInfo`]: /configuration/all#enablegitinfo
+[`environment`]: /configuration/all#environment
+[Google tag ID]: https://support.google.com/tagmanager/answer/12326985?hl=en
+[JSON]: https://datatracker.ietf.org/doc/html/rfc7159
+[permitted delimiter]: https://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html
+[TOML]: https://toml.io/en/latest
+[YAML]: https://yaml.org/spec/
--- /dev/null
- 1. [Localize] each entry
+---
+title: Menus
+description: Create menus by defining entries, localizing each entry, and rendering the resulting data structure.
+categories: []
+keywords: []
+aliases: [/extras/menus/]
+---
+
+## Overview
+
+To create a menu for your site:
+
+1. Define the menu entries
++1. [Localize](multilingual/#menus) each entry
+1. Render the menu with a [template]
+
+Create multiple menus, either flat or nested. For example, create a main menu for the header, and a separate menu for the footer.
+
+There are three ways to define menu entries:
+
+1. Automatically
+1. In front matter
+1. In site configuration
+
+> [!note]
+> Although you can use these methods in combination when defining a menu, the menu will be easier to conceptualize and maintain if you use one method throughout the site.
+
+## Define automatically
+
+To automatically define a menu entry for each top-level [section](g) of your site, enable the section pages menu in your site configuration.
+
+{{< code-toggle file=hugo >}}
+sectionPagesMenu = "main"
+{{< /code-toggle >}}
+
+This creates a menu structure that you can access with `site.Menus.main` in your templates. See [menu templates] for details.
+
+## Define in front matter
+
+To add a page to the "main" menu:
+
+{{< code-toggle file=content/about.md fm=true >}}
+title = 'About'
+menus = 'main'
+{{< /code-toggle >}}
+
+Access the entry with `site.Menus.main` in your templates. See [menu templates] for details.
+
+To add a page to the "main" and "footer" menus:
+
+{{< code-toggle file=content/contact.md fm=true >}}
+title = 'Contact'
+menus = ['main','footer']
+{{< /code-toggle >}}
+
+Access the entry with `site.Menus.main` and `site.Menus.footer` in your templates. See [menu templates] for details.
+
+> [!note]
+> The configuration key in the examples above is `menus`. The `menu` (singular) configuration key is an alias for `menus`.
+
+### Properties
+
+Use these properties when defining menu entries in front matter:
+
+{{% include "/_common/menu-entry-properties.md" %}}
+
+### Example
+
+This front matter menu entry demonstrates some of the available properties:
+
+{{< code-toggle file=content/products/software.md fm=true >}}
+title = 'Software'
+[menus.main]
+parent = 'Products'
+weight = 20
+pre = '<i class="fa-solid fa-code"></i>'
+[menus.main.params]
+class = 'center'
+{{< /code-toggle >}}
+
+Access the entry with `site.Menus.main` in your templates. See [menu templates] for details.
+
+## Define in site configuration
+
+See [configure menus](/configuration/menus/).
+
+## Localize
+
+Hugo provides two methods to localize your menu entries. See [multilingual].
+
+## Render
+
+See [menu templates].
+
+[menu templates]: /templates/menu/
+[multilingual]: /content-management/multilingual/#menus
+[template]: /templates/menu/
--- /dev/null
- Start descriptions in the functions and methods sections with "Returns", of for booelan values, "Reports whether".
+---
+title: Documentation
+description: Help us to improve the documentation by identifying issues and suggesting changes.
+categories: []
+keywords: []
+aliases: [/contribute/docs/]
+---
+
+## Introduction
+
+We welcome corrections and improvements to the documentation. The documentation lives in a separate repository from the main project. To contribute:
+
+- For corrections and improvements to existing documentation, submit issues and pull requests to the [documentation repository].
+- For documentation of new features, include the documentation changes in your pull request to the [project repository].
+
+## Guidelines
+
+### Style
+
+Follow Google's [developer documentation style guide].
+
+### Markdown
+
+Adhere to these Markdown conventions:
+
+- Use [ATX] headings (levels 2-4), not [setext] headings.
+- Use [fenced code blocks], not [indented code blocks].
+- Use hyphens, not asterisks, for unordered [list items].
+- Use [callouts](#callouts) instead of bold text for emphasis.
+- Do not mix [raw HTML] within Markdown.
+- Do not use bold text in place of a heading or description term (`dt`).
+- Remove consecutive blank lines.
+- Remove trailing spaces.
+
+### Glossary
+
+[Glossary] terms are defined on individual pages, providing a central repository for definitions, though these pages are not directly linked from the site.
+
+Definitions must be complete sentences, with the first sentence defining the term. Italicize the first occurrence of the term and any referenced glossary terms for consistency.
+
+Link to glossary terms using this syntax: `[term](g)`
+
+Term lookups are case-insensitive, ignore formatting, and support singular and plural forms. For example, all of these variations will link to the same glossary term:
+
+```text
+[global resource](g)
+[Global Resource](g)
+[Global Resources](g)
+[`Global Resources`](g)
+```
+
+Use the [glossary-term shortcode](#glossary-term) to insert a term definition:
+
+```text
+{{%/* glossary-term "global resource" */%}}
+```
+
+### Terminology
+
+Link to the [glossary] as needed and use terms consistently. Pay particular attention to:
+
+- "front matter" (two words, except when referring to the configuration key)
+- "home page" (two words)
+- "website" (one word)
+- "standalone" (one word, no hyphen)
+- "map" (instead of "dictionary")
+- "flag" (instead of "option" for command-line flags)
+- "client side" (noun), "client-side" (adjective)
+- "server side" (noun), "server-side" (adjective)
+- "Markdown" (capitalized)
+- "open-source" (hyphenated adjective)
+
+### Titles and headings
+
+- Use sentence-style capitalization.
+- Avoid formatted strings.
+- Keep them concise.
+
+### Page descriptions
+
+When writing the page `description` use imperative present tense when possible. For example:
+
+{{< code-toggle file=content/en/functions/data/_index.md" fm=true >}}
+title: Data functions
+linkTitle: data
+description: Use these functions to read local or remote data files.
+{{< /code-toggle >}}
+
+### Writing style
+
+Use active voice and present tense wherever possible.
+
+No → With Hugo you can build a static site.\
+Yes → Build a static site with Hugo.
+
+No → This will cause Hugo to generate HTML files in the `public` directory.\
+Yes → Hugo generates HTML files in the `public` directory.
+
+Use second person instead of third person.
+
+No → Users should exercise caution when deleting files.\
+Better → You must be cautious when deleting files.\
+Best → Be cautious when deleting files.
+
+Minimize adverbs.
+
+No → Hugo is extremely fast.\
+Yes → Hugo is fast.
+
+> [!note]
+> "It's an adverb, Sam. It's a lazy tool of a weak mind." (Outbreak, 1995).
+
+### Function and method descriptions
+
++Start descriptions in the functions and methods sections with "Returns", or for boolean values, "Reports whether".
+
+### File paths and names
+
+Enclose directory names, file names, and file paths in backticks, except when used in:
+
+- Page titles
+- Section headings (h1-h6)
+- Definition list terms
+- The `description` field in front matter
+
+### Miscellaneous
+
+Other best practices:
+
+- Introduce lists with a sentence or phrase, not directly under a heading.
+- Avoid bold text; use [callouts](#callouts) for emphasis.
+- Do not put description terms (`dt`) in backticks unless syntactically necessary.
+- Do not use Hugo's `ref` or `relref` shortcodes.
+- Prioritize current best practices over multiple options or historical information.
+- Use short, focused code examples.
+- Use [basic english] where possible for a global audience.
+
+## Front matter fields
+
+This site uses the front matter fields listed in the table below.
+
+Of the four required fields, only `title` and `description` require data.
+
+```text
+title: The title
+description: The description
+categories: []
+keywords: []
+```
+
+This example demonstrates the minimum required front matter fields.
+
+If quotation marks are required, prefer single quotes to double quotes when possible.
+
+Seq|Field|Description|Required
+--:|:--|:--|:--
+1|`title`|The page title|:heavy_check_mark:|
+2|`linkTitle`|A short version of the page title||
+3|`description`|A complete sentence describing the page|:heavy_check_mark:|
+4|`categories`|An array of terms in the categories taxonomy|:heavy_check_mark: [^1]|
+5|`keywords`|An array of keywords used to identify related content|:heavy_check_mark: [^1]|
+6|`publishDate`|Applicable to news items: the publication date||
+7|`params.altTitle`|An alternate title: used in the "see also" panel if provided||
+8|`params.functions_and_methods.aliases`|Applicable to function and method pages: an array of alias names||
+9|`params.functions_and_methods.returnType`|Applicable to function and method pages: the data type returned||
+10|`params.functions_and_methods.signatures`|Applicable to function and method pages: an array of signatures||
+11|`params.hide_in_this_section`|Whether to hide the "in this section" panel||
+12|`params.minversion`|Applicable to the quick start page: the minimum Hugo version required||
+13|`params.permalink`|Reserved for use by the news content adapter||
+14|`params.reference (used in glossary term)`|Applicable to glossary entries: a URL for additional information||
+15|`params.show_publish_date`|Whether to show the `publishDate` when rendering the page||
+16|`weight`|The page weight||
+17|`aliases`|Previous URLs used to access this page||
+18|`expirydate`|The expiration date||
+
+[^1]: The field is required, but its data is not.
+
+## Related content
+
+When available, the "See also" sidebar displays related pages using Hugo's [related content] feature, based on front matter keywords. We ensure consistent keyword usage by validating them against `data/keywords.yaml` during the build process. If a keyword is not found, you'll be alerted and must either modify the keyword or update the data file. This validation process helps to refine the related content for better results.
+
+If the title in the "See also" sidebar is ambiguous or the same as another page, you can define an alternate title in the front matter:
+
+{{< code-toggle file=hugo >}}
+title = "Long descriptive title"
+linkTitle = "Short title"
+[params]
+altTitle = "Whatever you want"
+{{< /code-toggle >}}
+
+Use of the alternate title is limited to the "See also" sidebar.
+
+> [!note]
+> Think carefully before setting the `altTitle`. Use it only when absolutely necessary.
+
+## Code examples
+
+With examples of template code:
+
+- Indent with two spaces.
+- Insert a space after an opening action delimiter.
+- Insert a space before a closing action delimiter.
+- Do not add white space removal syntax to action delimiters unless required. For example, inline elements like `img` and `a` require whitespace removal on both sides.
+
+```go-html-template
+{{ if eq $foo $bar }}
+ {{ fmt.Printf "%s is %s" $foo $bar }}
+{{ end }}
+```
+
+### Fenced code blocks
+
+Always specify the language.
+
+When providing a Mardown example, set the code language to "text" to prevent
+erroneous lexing/highlighting of shortcode calls.
+
+````text
+```go-html-template
+{{ if eq $foo "bar" }}
+ {{ print "foo is bar" }}
+{{ end }}
+```
+````
+
+To include a filename header and copy-to-clipboard button:
+
+````text
+```go-html-template {file="layouts/partials/foo.html" copy=true}
+{{ if eq $foo "bar" }}
+ {{ print "foo is bar" }}
+{{ end }}
+```
+````
+
+To wrap the code block within an initially-opened `details` element using a non-default summary:
+
+````text
+```go-html-template {details=true open=true summary="layouts/partials/foo.html" copy=true}
+{{ if eq $foo "bar" }}
+ {{ print "foo is bar" }}
+{{ end }}
+```
+````
+
+### Shortcode calls
+
+Use this syntax :
+
+````text
+```text
+{{</*/* foo */*/>}}
+{{%/*/* foo */*/%}}
+```
+````
+
+### Site configuration
+
+Use the [code-toggle shortcode](#code-toggle) to include site configuration examples:
+
+```text
+{{</* code-toggle file=hugo */>}}
+baseURL = 'https://example.org/'
+languageCode = 'en-US'
+title = 'My Site'
+{{</* /code-toggle */>}}
+```
+
+### Front matter
+
+Use the [code-toggle shortcode](#code-toggle) to include front matter examples:
+
+```text
+{{</* code-toggle file=content/posts/my-first-post.md fm=true */>}}
+title = 'My first post'
+date = 2023-11-09T12:56:07-08:00
+draft = false
+{{</* /code-toggle */>}}
+```
+
+## Callouts
+
+To visually emphasize important information, use callouts (admonitions). Callout types are case-insensitive. Effective March 8, 2025, we utilize only three of the five available types.
+
+- note (272 instances)
+- warning (2 instances)
+- caution (1 instance)
+
+Limiting the number of callout types helps us to use them consistently.
+
+```text
+> [!note]
+> Useful information that users should know, even when skimming content.
+```
+
+> [!note]
+> Useful information that users should know, even when skimming content.
+
+```text
+> [!warning]
+> Urgent info that needs immediate user attention to avoid problems.
+```
+
+> [!warning]
+> Urgent info that needs immediate user attention to avoid problems.
+
+```text
+> [!caution]
+> Advises about risks or negative outcomes of certain actions.
+```
+
+> [!caution]
+> Advises about risks or negative outcomes of certain actions.
+
+```text
+> [!tip]
+> Helpful advice for doing things better or more easily.
+```
+
+> [!tip]
+> Helpful advice for doing things better or more easily.
+
+```text
+> [!important]
+> Key information users need to know to achieve their goal.
+```
+
+> [!important]
+> Key information users need to know to achieve their goal.
+
+
+
+## Shortcodes
+
+These shortcodes are commonly used throughout the documentation. Other shortcodes are available for specialized use.
+
+### code-toggle
+
+Use the `code-toggle` shortcode to display examples of site configuration, front matter, or data files. This shortcode takes these arguments:
+
+config
+: (`string`) The section of `site.Data.docs.config` to render.
+
+copy
+: (`bool`) Whether to display a copy-to-clipboard button. Default is `false`.
+
+datakey:
+: (`string`) The section of `site.Data.docs` to render.
+
+file
+: (`string`) The file name to display above the rendered code. Omit the file extension for site configuration examples.
+
+fm
+: (`bool`) Whether to render the code as front matter. Default is `false`.
+
+skipHeader
+: (`bool`) Whether to omit top-level key(s) when rendering a section of `site.Data.docs.config`.
+
+```text
+{{</* code-toggle file=hugo copy=true */>}}
+baseURL = 'https://example.org/'
+languageCode = 'en-US'
+title = 'My Site'
+{{</* /code-toggle */>}}
+```
+
+### deprecated-in
+
+Use the `deprecated-in` shortcode to indicate that a feature is deprecated:
+
+```text
+{{</* deprecated-in 0.144.0 */>}}
+
+Use [`hugo.IsServer`] instead.
+
+[`hugo.IsServer`]: /functions/hugo/isserver/
+{{</* /deprecated-in */>}}
+```
+
+### eturl
+
+Use the embedded template URL (`eturl`) shortcode to insert an absolute URL to the source code for an embedded template. The shortcode takes a single argument, the base file name of the template (omit the file extension).
+
+```text
+This is a link to the [embedded alias template].
+
+[embedded alias template]: {{%/* eturl alias */%}}
+```
+
+### glossary-term
+
+Use the `glossary-term` shortcode to insert the definition of the given glossary term.
+
+```text
+{{%/* glossary-term scalar */%}}
+```
+
+### include
+
+Use the `include` shortcode to include content from another page.
+
+```text
+{{%/* include "_common/glob-patterns.md" */%}}
+```
+
+### new-in
+
+Use the `new-in` shortcode to indicate a new feature:
+
+```text
+{{</* new-in 0.144.0 /*/>}}
+```
+
+You can also include details:
+
+```text
+{{</* new-in 0.144.0 */>}}
+This is a new feature.
+{{</* /new-in */>}}
+```
+
+## New features
+
+Use the [new-in shortcode](#new-in) to indicate a new feature:
+
+```text
+{{</* new-in 0.144.0 */>}}
+```
+
+The "new in" label will be hidden if the specified version is older than a predefined threshold, based on differences in major and minor versions. See [details](https://github.com/gohugoio/hugoDocs/blob/master/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/new-in.html).
+
+## Deprecated features
+
+Use the [deprecated-in shorcode](#deprecated-in) shortcode to indicate that a feature is deprecated:
+
+```text
+{{</* deprecated-in 0.144.0 */>}}
+Use [`hugo.IsServer`] instead.
+
+[`hugo.IsServer`]: /functions/hugo/isserver/
+{{</* /deprecated-in */>}}
+```
+
+When deprecating a function or method, add something like this to front matter:
+
+{{< code-toggle file=content/something/foo.md fm=true >}}
+expiryDate: 2027-02-17 # deprecated 2025-02-17 in v0.144.0
+{{< /code-toggle >}}
+
+Set the `expiryDate` to two years from the date of deprecation, and add a brief front matter comment to explain the setting.
+
+## GitHub workflow
+
+> [!note]
+> This section assumes that you have a working knowledge of Git and GitHub, and are comfortable working on the command line.
+
+Use this workflow to create and submit pull requests.
+
+### Step 1
+
+Fork the [documentation repository].
+
+### Step 2
+
+Clone your fork.
+
+### Step 3
+
+Create a new branch with a descriptive name that includes the corresponding issue number, if any:
+
+```sh
+git checkout -b restructure-foo-page-99999
+```
+
+### Step 4
+
+Make changes.
+
+### Step 5
+
+Build the site locally to preview your changes.
+
+### Step 6
+
+Commit your changes with a descriptive commit message:
+
+- Provide a summary on the first line, typically 50 characters or less, followed by a blank line.
+ - Begin the summary with one of `content`, `theme`, `config`, `all`, or `misc`, followed by a colon, a space, and a brief description of the change beginning with a capital letter
+ - Use imperative present tense
+- Optionally, provide a detailed description where each line is 72 characters or less, followed by a blank line.
+- Optionally, add one or more "Fixes" or "Closes" keywords, each on its own line, referencing the [issues] addressed by this change.
+
+For example:
+
+```text
+git commit -m "content: Restructure the taxonomy page
+
+This restructures the taxonomy page by splitting topics into logical
+sections, each with one or more examples.
+
+Fixes #9999
+Closes #9998"
+```
+
+### Step 7
+
+Push the new branch to your fork of the documentation repository.
+
+### Step 8
+
+Visit the [documentation repository] and create a pull request (PR).
+
+### Step 9
+
+A project maintainer will review your PR and may request changes. You may delete your branch after the maintainer merges your PR.
+
+[ATX]: https://spec.commonmark.org/0.30/#atx-headings
+[basic english]: https://simple.wikipedia.org/wiki/Basic_English
+[basic english]: https://simple.wikipedia.org/wiki/Basic_English
+[developer documentation style guide]: https://developers.google.com/style
+[documentation repository]: https://github.com/gohugoio/hugoDocs/
+[fenced code blocks]: https://spec.commonmark.org/0.30/#fenced-code-blocks
+[glossary]: /quick-reference/glossary/
+[indented code blocks]: https://spec.commonmark.org/0.30/#indented-code-blocks
+[issues]: https://github.com/gohugoio/hugoDocs/issues
+[list items]: https://spec.commonmark.org/0.30/#list-items
+[project repository]: https://github.com/gohugoio/hugo
+[raw HTML]: https://spec.commonmark.org/0.30/#raw-html
+[related content]: /content-management/related-content/
+[setext]: https://spec.commonmark.org/0.30/#setext-heading
--- /dev/null
- : {{< new-in 0.116.0 />}}
+---
+title: collections.Where
+description: Returns the given collection, removing elements that do not satisfy the comparison condition.
+categories: []
+keywords: []
+params:
+ functions_and_methods:
+ aliases: [where]
+ returnType: any
+ signatures: ['collections.Where COLLECTION KEY [OPERATOR] VALUE']
+aliases: [/functions/where]
+---
+
+The `where` function returns the given collection, removing elements that do not satisfy the comparison condition. The comparison condition is composed of the `KEY`, `OPERATOR`, and `VALUE` arguments:
+
+```text
+collections.Where COLLECTION KEY [OPERATOR] VALUE
+ --------------------
+ comparison condition
+```
+
+Hugo will test for equality if you do not provide an `OPERATOR` argument. For example:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Section" "books" }}
+{{ $books := where .Site.Data.books "genres" "suspense" }}
+```
+
+## Arguments
+
+The where function takes three or four arguments. The `OPERATOR` argument is optional.
+
+COLLECTION
+: (`any`) A [page collection](g) or a [slice](g) of [maps](g).
+
+KEY
+: (`string`) The key of the page or map value to compare with `VALUE`. With page collections, commonly used comparison keys are `Section`, `Type`, and `Params`. To compare with a member of the page `Params` map, [chain](g) the subkey as shown below:
+
+```go-html-template
+{{ $result := where .Site.RegularPages "Params.foo" "bar" }}
+```
+
+OPERATOR
+: (`string`) The logical comparison [operator](#operators).
+
+VALUE
+: (`any`) The value with which to compare. The values to compare must have comparable data types. For example:
+
+Comparison|Result
+:--|:--
+`"123" "eq" "123"`|`true`
+`"123" "eq" 123`|`false`
+`false "eq" "false"`|`false`
+`false "eq" false`|`true`
+
+When one or both of the values to compare is a slice, use the `in`, `not in`, or `intersect` operators as described below.
+
+## Operators
+
+Use any of the following logical operators:
+
+`=`, `==`, `eq`
+: (`bool`) Reports whether the given field value is equal to `VALUE`.
+
+`!=`, `<>`, `ne`
+: (`bool`) Reports whether the given field value is not equal to `VALUE`.
+
+`>=`, `ge`
+: (`bool`) Reports whether the given field value is greater than or equal to `VALUE`.
+
+`>`, `gt`
+: `true` Reports whether the given field value is greater than `VALUE`.
+
+`<=`, `le`
+: (`bool`) Reports whether the given field value is less than or equal to `VALUE`.
+
+`<`, `lt`
+: (`bool`) Reports whether the given field value is less than `VALUE`.
+
+`in`
+: (`bool`) Reports whether the given field value is a member of `VALUE`. Compare string to slice, or string to string. See [details](/functions/collections/in).
+
+`not in`
+: (`bool`) Reports whether the given field value is not a member of `VALUE`. Compare string to slice, or string to string. See [details](/functions/collections/in).
+
+`intersect`
+: (`bool`) Reports whether the given field value (a slice) contains one or more elements in common with `VALUE`. See [details](/functions/collections/intersect).
+
+`like`
- {{< new-in 0.116.0 />}}
-
+: (`bool`) Reports whether the given field value matches the [regular expression](g) specified in `VALUE`. Use the `like` operator to compare `string` values. The `like` operator returns `false` when comparing other data types to the regular expression.
+
+> [!note]
+> The examples below perform comparisons within a page collection, but the same comparisons are applicable to a slice of maps.
+
+## String comparison
+
+Compare the value of the given field to a [`string`](g):
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Section" "eq" "books" }}
+{{ $pages := where .Site.RegularPages "Section" "ne" "books" }}
+```
+
+## Numeric comparison
+
+Compare the value of the given field to an [`int`](g) or [`float`](g):
+
+```go-html-template
+{{ $books := where site.RegularPages "Section" "eq" "books" }}
+
+{{ $pages := where $books "Params.price" "eq" 42 }}
+{{ $pages := where $books "Params.price" "ne" 42.67 }}
+{{ $pages := where $books "Params.price" "ge" 42 }}
+{{ $pages := where $books "Params.price" "gt" 42.67 }}
+{{ $pages := where $books "Params.price" "le" 42 }}
+{{ $pages := where $books "Params.price" "lt" 42.67 }}
+```
+
+## Boolean comparison
+
+Compare the value of the given field to a [`bool`](g):
+
+```go-html-template
+{{ $books := where site.RegularPages "Section" "eq" "books" }}
+
+{{ $pages := where $books "Params.fiction" "eq" true }}
+{{ $pages := where $books "Params.fiction" "eq" false }}
+{{ $pages := where $books "Params.fiction" "ne" true }}
+{{ $pages := where $books "Params.fiction" "ne" false }}
+```
+
+## Member comparison
+
+Compare a [`scalar`](g) to a [`slice`](g).
+
+For example, to return a collection of pages where the `color` page parameter is either "red" or "yellow":
+
+```go-html-template
+{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }}
+
+{{ $colors := slice "red" "yellow" }}
+{{ $pages := where $fruit "Params.color" "in" $colors }}
+```
+
+To return a collection of pages where the "color" page parameter is neither "red" nor "yellow":
+
+```go-html-template
+{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }}
+
+{{ $colors := slice "red" "yellow" }}
+{{ $pages := where $fruit "Params.color" "not in" $colors }}
+```
+
+## Intersection comparison
+
+Compare a `slice` to a `slice`, returning collection elements with common values. This is frequently used when comparing taxonomy terms.
+
+For example, to return a collection of pages where any of the terms in the "genres" taxonomy are "suspense" or "romance":
+
+```go-html-template
+{{ $books := where site.RegularPages "Section" "eq" "books" }}
+
+{{ $genres := slice "suspense" "romance" }}
+{{ $pages := where $books "Params.genres" "intersect" $genres }}
+```
+
+## Regular expression comparison
+
+To return a collection of pages where the "author" page parameter begins with either "victor" or "Victor":
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Params.author" "like" `(?i)^victor` }}
+```
+
+{{% include "/_common/functions/regular-expressions.md" %}}
+
+> [!note]
+> Use the `like` operator to compare string values. Comparing other data types will result in an empty collection.
+
+## Date comparison
+
+### Predefined dates
+
+There are four predefined front matter dates: [`date`], [`publishDate`], [`lastmod`], and [`expiryDate`]. Regardless of the front matter data format (TOML, YAML, or JSON) these are [`time.Time`] values, allowing precise comparisons.
+
+For example, to return a collection of pages that were created before the current year:
+
+```go-html-template
+{{ $startOfYear := time.AsTime (printf "%d-01-01" now.Year) }}
+{{ $pages := where .Site.RegularPages "Date" "lt" $startOfYear }}
+```
+
+### Custom dates
+
+With custom front matter dates, the comparison depends on the front matter data format (TOML, YAML, or JSON).
+
+> [!note]
+> Using TOML for pages with custom front matter dates enables precise date comparisons.
+
+With TOML, date values are first-class citizens. TOML has a date data type while JSON and YAML do not. If you quote a TOML date, it is a string. If you do not quote a TOML date value, it is [`time.Time`] value, enabling precise comparisons.
+
+In the TOML example below, note that the event date is not quoted.
+
+```text {file="content/events/2024-user-conference.md"}
++++
+title = '2024 User Conference"
+eventDate = 2024-04-01
++++
+```
+
+To return a collection of future events:
+
+```go-html-template
+{{ $events := where .Site.RegularPages "Type" "events" }}
+{{ $futureEvents := where $events "Params.eventDate" "gt" now }}
+```
+
+When working with YAML or JSON, or quoted TOML values, custom dates are strings; you cannot compare them with `time.Time` values. String comparisons may be possible if the custom date layout is consistent from one page to the next. To be safe, filter the pages by ranging through the collection:
+
+```go-html-template
+{{ $events := where .Site.RegularPages "Type" "events" }}
+{{ $futureEvents := slice }}
+{{ range $events }}
+ {{ if gt (time.AsTime .Params.eventDate) now }}
+ {{ $futureEvents = $futureEvents | append . }}
+ {{ end }}
+{{ end }}
+```
+
+## Nil comparison
+
+To return a collection of pages where the "color" parameter is present in front matter, compare to `nil`:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Params.color" "ne" nil }}
+```
+
+To return a collection of pages where the "color" parameter is not present in front matter, compare to `nil`:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Params.color" "eq" nil }}
+```
+
+In both examples above, note that `nil` is not quoted.
+
+## Nested comparison
+
+These are equivalent:
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Type" "tutorials" }}
+{{ $pages = where $pages "Params.level" "eq" "beginner" }}
+```
+
+```go-html-template
+{{ $pages := where (where .Site.RegularPages "Type" "tutorials") "Params.level" "eq" "beginner" }}
+```
+
+## Portable section comparison
+
+Useful for theme authors, avoid hardcoding section names by using the `where` function with the [`MainSections`] method on a `Site` object.
+
+```go-html-template
+{{ $pages := where .Site.RegularPages "Section" "in" .Site.MainSections }}
+```
+
+With this construct, a theme author can instruct users to specify their main sections in the site configuration:
+
+{{< code-toggle file=hugo >}}
+mainSections = ['blog','galleries']
+{{< /code-toggle >}}
+
+If `mainSections` is not defined in the site configuration, the `MainSections` method returns a slice with one element---the top-level section with the most pages.
+
+## Boolean/undefined comparison
+
+Consider this site content:
+
+```text
+content/
+├── posts/
+│ ├── _index.md
+│ ├── post-1.md <-- front matter: exclude = false
+│ ├── post-2.md <-- front matter: exclude = true
+│ └── post-3.md <-- front matter: exclude not defined
+└── _index.md
+```
+
+The first two pages have an "exclude" field in front matter, but the last page does not. When testing for _equality_, the third page is _excluded_ from the result. When testing for _inequality_, the third page is _included_ in the result.
+
+### Equality test
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "eq" false }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 1</a></li>
+</ul>
+```
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "eq" true }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-2/">Post 2</a></li>
+</ul>
+```
+
+### Inequality test
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "ne" false }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-2/">Post 2</a></li>
+ <li><a href="/posts/post-3/">Post 3</a></li>
+</ul>
+```
+
+This template:
+
+```go-html-template
+<ul>
+ {{ range where .Site.RegularPages "Params.exclude" "ne" true }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 1</a></li>
+ <li><a href="/posts/post-3/">Post 3</a></li>
+</ul>
+```
+
+To exclude a page with an undefined field from a boolean _inequality_ test:
+
+1. Create a collection using a boolean comparison
+1. Create a collection using a nil comparison
+1. Subtract the second collection from the first collection using the [`collections.Complement`] function.
+
+This template:
+
+```go-html-template
+{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" true }}
+{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }}
+<ul>
+ {{ range $p1 | complement $p2 }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 1</a></li>
+</ul>
+```
+
+This template:
+
+```go-html-template
+{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" false }}
+{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }}
+<ul>
+ {{ range $p1 | complement $p2 }}
+ <li><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></li>
+ {{ end }}
+</ul>
+```
+
+Is rendered to:
+
+```html
+<ul>
+ <li><a href="/posts/post-1/">Post 2</a></li>
+</ul>
+```
+
+[`collections.Complement`]: /functions/collections/complement/
+[`date`]: /methods/page/date/
+[`lastmod`]: /methods/page/lastmod/
+[`MainSections`]: /methods/site/mainsections/
+[`time.Time`]: https://pkg.go.dev/time#Time
--- /dev/null
- ```go-html-template
- {{ with resources.Get "sass/main.scss" }}
- {{ $opts := dict
- "enableSourceMap" (not hugo.IsProduction)
- "outputStyle" (cond hugo.IsProduction "compressed" "expanded")
- "targetPath" "css/main.css"
- "transpiler" "libsass"
- }}
- {{ with . | toCSS $opts }}
- {{ if hugo.IsProduction }}
- {{ with . | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- {{ else }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- {{ end }}
- {{ end }}
- ```
-
+---
+title: css.Sass
+description: Transpiles Sass to CSS.
+categories: []
+keywords: []
+params:
+ functions_and_methods:
+ aliases: [toCSS]
+ returnType: resource.Resource
+ signatures: ['css.Sass [OPTIONS] RESOURCE']
+---
+
+{{< new-in 0.128.0 />}}
+
- transpiler
- : (`string`) The transpiler to use, either `libsass` (default) or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass) below.
-
- targetPath
- : (`string`) If not set, the transformed resource's target path will be the original path of the asset file with its extension replaced by `.css`.
-
- vars
- : (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/).
-
- ```scss
- // LibSass
- @import "hugo:vars";
+Transpile Sass to CSS using the LibSass transpiler included in Hugo's extended and extended/deploy editions, or [install Dart Sass](#dart-sass) to use the latest features of the Sass language.
+
+Sass has two forms of syntax: [SCSS] and [indented]. Hugo supports both.
+
+[scss]: https://sass-lang.com/documentation/syntax#scss
+[indented]: https://sass-lang.com/documentation/syntax#the-indented-syntax
+
+## Options
+
- // Dart Sass
- @use "hugo:vars" as v;
- ```
++enableSourceMap
++: (`bool`) Whether to generate a source map. Default is `false`.
+
- : (`string`) Output styles available to LibSass include `nested` (default), `expanded`, `compact`, and `compressed`. Output styles available to Dart Sass include `expanded` (default) and `compressed`.
++includePaths
++: (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements.
+
+outputStyle
- : (`int`) Precision of floating point math. Not applicable to Dart Sass.
++: (`string`) The output style of the resulting CSS. With LibSass, one of `nested` (default), `expanded`, `compact`, or `compressed`. With Dart Sass, either `expanded` (default) or `compressed`.
+
+precision
- enableSourceMap
- : (`bool`) Whether to generate a source map. Default is `false`.
++: (`int`) The precision of floating point math. Applicable to LibSass. Default is `8`.
+
- : (`bool`) Whether to embed sources in the generated source map. Not applicable to LibSass. Default is `false`.
++silenceDeprecations
++: {{< new-in 0.139.0 />}}
++: (`slice`) A slice of deprecation IDs to silence. IDs are enclosed in brackets within Dart Sass warning messages (e.g., `import` in `WARN Dart Sass: DEPRECATED [import]`). Applicable to Dart Sass. Default is `false`.
++
++silenceDependencyDeprecations
++: {{< new-in 0.146.0 />}}
++: (`bool`) Whether to silence deprecation warnings from dependencies, where a dependency is considered any file transitively imported through a load path. This does not apply to `@warn` or `@debug` rules.Default is `false`.
+
+sourceMapIncludeSources
- includePaths
- : (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements.
++: (`bool`) Whether to embed sources in the generated source map. Applicable to Dart Sass. Default is `false`.
+
- ```go-html-template
- {{ $opts := dict
- "transpiler" "dartsass"
- "targetPath" "css/style.css"
- "vars" site.Params.styles
- "enableSourceMap" (not hugo.IsProduction)
- "includePaths" (slice "node_modules/bootstrap/scss")
- }}
- {{ with resources.Get "sass/main.scss" | toCSS $opts | minify | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
++targetPath
++: (`string`) The publish path for the transformed resource, relative to the[`publishDir`]. If unset, the target path defaults to the asset's original path with a `.css` extension.
++
++transpiler
++: (`string`) The transpiler to use, either `libsass` or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass). Default is `libsass`.
++
++vars
++: (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/).
++
++ ```scss
++ // LibSass
++ @import "hugo:vars";
++
++ // Dart Sass
++ @use "hugo:vars" as v;
++ ```
+
- silenceDeprecations
- : (`slice`) {{< new-in 0.139.0 />}} A slice of deprecation IDs to silence. The deprecation IDs are printed to in the warning message, e.g "import" in `WARN Dart Sass: DEPRECATED [import] ...`. This is for Dart Sass only.
-
++## Example
++
++```go-html-template {copy=true}
++{{ with resources.Get "sass/main.scss" }}
++ {{ $opts := dict
++ "enableSourceMap" (not hugo.IsProduction)
++ "outputStyle" (cond hugo.IsProduction "compressed" "expanded")
++ "targetPath" "css/main.css"
++ "transpiler" "dartsass"
++ "vars" site.Params.styles
++ "includePaths" (slice "node_modules/bootstrap/scss")
++ }}
++ {{ with . | toCSS $opts }}
++ {{ if hugo.IsProduction }}
++ {{ with . | fingerprint }}
++ <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
++ {{ end }}
++ {{ else }}
++ <link rel="stylesheet" href="{{ .RelPermalink }}">
++ {{ end }}
++ {{ end }}
+{{ end }}
+```
+
- If you are using GitHub Pages for the first time with your repository, GitHub provides a [starter workflow] for Hugo that includes Dart Sass. This is the simplest way to get started.
-
+## Dart Sass
+
+Hugo's extended and extended/deploy editions include [LibSass] to transpile Sass to CSS. In 2020, the Sass team deprecated LibSass in favor of [Dart Sass].
+
+Use the latest features of the Sass language by installing Dart Sass in your development and production environments.
+
+### Installation overview
+
+Dart Sass is compatible with Hugo v0.114.0 and later.
+
+If you have been using Embedded Dart Sass[^1] with Hugo v0.113.0 and earlier, uninstall Embedded Dart Sass, then install Dart Sass. If you have installed both, Hugo will use Dart Sass.
+
+If you install Hugo as a [Snap package] there is no need to install Dart Sass. The Hugo Snap package includes Dart Sass.
+
+[^1]: In 2023, the Sass team deprecated Embedded Dart Sass in favor of Dart Sass.
+
+### Installing in a development environment
+
+When you install Dart Sass somewhere in your PATH, Hugo will find it.
+
+OS|Package manager|Site|Installation
+:--|:--|:--|:--
+Linux|Homebrew|[brew.sh]|`brew install sass/sass/sass`
+Linux|Snap|[snapcraft.io]|`sudo snap install dart-sass`
+macOS|Homebrew|[brew.sh]|`brew install sass/sass/sass`
+Windows|Chocolatey|[chocolatey.org]|`choco install sass`
+Windows|Scoop|[scoop.sh]|`scoop install sass`
+
+You may also install [prebuilt binaries] for Linux, macOS, and Windows.
+
+Run `hugo env` to list the active transpilers.
+
++> [!note]
++> If you build Hugo from source and run `mage test -v`, the test will fail if you install Dart Sass as a Snap package. This is due to the Snap package's strict confinement model.
++
+### Installing in a production environment
+
+For [CI/CD](g) deployments (e.g., GitHub Pages, GitLab Pages, Netlify, etc.) you must edit the workflow to install Dart Sass before Hugo builds the site[^2]. Some providers allow you to use one of the package managers above, or you can download and extract one of the prebuilt binaries.
+
+[^2]: You do not have to do this if (a) you have not modified the assets cache location, and (b) you have not set `useResourceCacheWhen` to `never` in your [site configuration], and (c) you add and commit your `resources` directory to your repository.
+
+#### GitHub Pages
+
+To install Dart Sass for your builds on GitHub Pages, add this step to the GitHub Pages workflow file:
+
+```yaml
+- name: Install Dart Sass
+ run: sudo snap install dart-sass
+```
+
- ### Example
-
- To transpile with Dart Sass, set `transpiler` to `dartsass` in the options map passed to `css.Sass`. For example:
-
- ```go-html-template
- {{ with resources.Get "sass/main.scss" }}
- {{ $opts := dict
- "enableSourceMap" (not hugo.IsProduction)
- "outputStyle" (cond hugo.IsProduction "compressed" "expanded")
- "targetPath" "css/main.css"
- "transpiler" "dartsass"
- }}
- {{ with . | toCSS $opts }}
- {{ if hugo.IsProduction }}
- {{ with . | fingerprint }}
- <link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
- {{ end }}
- {{ else }}
- <link rel="stylesheet" href="{{ .RelPermalink }}">
- {{ end }}
- {{ end }}
- {{ end }}
- ```
-
- ### Miscellaneous
-
- If you build Hugo from source and run `mage test -v`, the test will fail if you install Dart Sass as a Snap package. This is due to the Snap package's strict confinement model.
-
+#### GitLab Pages
+
+To install Dart Sass for your builds on GitLab Pages, the `.gitlab-ci.yml` file should look something like this:
+
+```yaml
+variables:
+ HUGO_VERSION: 0.144.2
+ DART_SASS_VERSION: 1.85.0
+ GIT_DEPTH: 0
+ GIT_STRATEGY: clone
+ GIT_SUBMODULE_STRATEGY: recursive
+ TZ: America/Los_Angeles
+image:
+ name: golang:1.20-buster
+pages:
+ script:
+ # Install Dart Sass
+ - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
+ - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
+ - cp -r dart-sass/* /usr/local/bin
+ - rm -rf dart-sass*
+ # Install Hugo
+ - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ - apt install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ # Build
+ - hugo --gc --minify
+ artifacts:
+ paths:
+ - public
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+```
+
+#### Netlify
+
+To install Dart Sass for your builds on Netlify, the `netlify.toml` file should look something like this:
+
+```toml
+[build.environment]
+HUGO_VERSION = "0.144.2"
+DART_SASS_VERSION = "1.85.0"
+NODE_VERSION = "22"
+TZ = "America/Los_Angeles"
+
+[build]
+publish = "public"
+command = """\
+ curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ rm dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ export PATH=/opt/build/repo/dart-sass:$PATH && \
+ hugo --gc --minify \
+ """
+```
+
+[brew.sh]: https://brew.sh/
+[chocolatey.org]: https://community.chocolatey.org/packages/sass
+[dart sass]: https://sass-lang.com/dart-sass
+[libsass]: https://sass-lang.com/libsass
+[prebuilt binaries]: https://github.com/sass/dart-sass/releases/latest
+[scoop.sh]: https://scoop.sh/#/apps?q=sass
+[site configuration]: /configuration/build/
+[snap package]: /installation/linux/#snap
+[snapcraft.io]: https://snapcraft.io/dart-sass
+[starter workflow]: https://github.com/actions/starter-workflows/blob/main/pages/hugo.yml
++[`publishDir`]: /configuration/all/#publishdir
--- /dev/null
- Use the `template` function to execute [embedded templates]. For example:
+---
+title: template
+description: Executes the given template, optionally passing context.
+categories: []
+keywords: []
+params:
+ functions_and_methods:
+ aliases: []
+ returnType:
+ signatures: ['template NAME [CONTEXT]']
+---
+
- [embedded templates]: /templates/embedded/
++Use the `template` function to execute any of these [embedded templates](g):
++
++- [`disqus.html`]
++- [`google_analytics.html`]
++- [`opengraph.html`]
++- [`pagination.html`]
++- [`schema.html`]
++- [`twitter_cards.html`]
++
++
++
++For example:
+
+```go-html-template
+{{ range (.Paginate .Pages).Pages }}
+ <h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
+{{ end }}
+{{ template "_internal/pagination.html" . }}
+```
+
+You can also use the `template` function to execute a defined template:
+
+```go-html-template
+{{ template "foo" (dict "answer" 42) }}
+
+{{ define "foo" }}
+ {{ printf "The answer is %v." .answer }}
+{{ end }}
+```
+
+The example above can be rewritten using an [inline partial] template:
+
+```go-html-template
+{{ partial "inline/foo.html" (dict "answer" 42) }}
+
+{{ define "partials/inline/foo.html" }}
+ {{ printf "The answer is %v." .answer }}
+{{ end }}
+```
+
++The key distinctions between the preceding two examples are:
++
++1. Inline partials are globally scoped. That means that an inline partial defined in _one_ template may be called from _any_ template.
++2. Leveraging the [`partialCached`] function when calling an inline partial allows for performance optimization through result caching.
++3. An inline partial can [`return`] a value of any data type instead of rendering a string.
++
+{{% include "/_common/functions/go-template/text-template.md" %}}
+
++[`disqus.html`]: /templates/embedded/#disqus
++[`google_analytics.html`]: /templates/embedded/#google-analytics
++[`opengraph.html`]: /templates/embedded/#open-graph
++[`pagination.html`]: /templates/embedded/#pagination
++[`partialCached`]: /functions/partials/includecached/
+[`partial`]: /functions/partials/include/
++[`return`]: /functions/go-template/return/
++[`schema.html`]: /templates/embedded/#schema
++[`twitter_cards.html`]: /templates/embedded/#x-twitter-cards
+[inline partial]: /templates/partial/#inline-partials
--- /dev/null
--- /dev/null
++---
++title: templates.Current
++description: Returns information about the currently executing template.
++categories: []
++keywords: []
++params:
++ functions_and_methods:
++ aliases: []
++ returnType: tpl.CurrentTemplateInfo
++ signatures: [templates.Current]
++---
++
++> [!note]
++> This function is experimental and subject to change.
++
++{{< new-in 0.146.0 />}}
++
++The `templates.Current` function provides introspection capabilities, allowing you to access details about the currently executing templates. This is useful for debugging complex template hierarchies and understanding the flow of execution during rendering.
++
++## Methods
++
++Ancestors
++: (`tpl.CurrentTemplateInfos`) Returns a slice containing information about each template in the current execution chain, starting from the parent of the current template and going up towards the initial template called. It excludes any base template applied via `define` and `block`. You can chain the `Reverse` method to this result to get the slice in chronological execution order.
++
++Base
++: (`tpl.CurrentTemplateInfoCommonOps`) Returns an object representing the base template that was applied to the current template, if any. This may be `nil`.
++
++Filename
++: (`string`) Returns the absolute path of the current template. This will be empty for embedded templates.
++
++Name
++: (`string`) Returns the name of the current template. This is usually the path relative to the layouts directory.
++
++Parent
++: (`tpl.CurrentTemplateInfo`) Returns an object representing the parent of the current template, if any. This may be `nil`.
++
++## Examples
++
++The examples below help visualize template execution and require a `debug` parameter set to `true` in your site configuration:
++
++{{< code-toggle file=hugo >}}
++[params]
++debug = true
++{{< /code-toggle >}}
++
++### Boundaries
++
++To visually mark where a template begins and ends execution:
++
++```go-html-template {file="layouts/_default/single.html"}
++{{ define "main" }}
++ {{ if site.Params.debug }}
++ <div class="debug">[entering {{ templates.Current.Filename }}]</div>
++ {{ end }}
++
++ <h1>{{ .Title }}</h1>
++ {{ .Content }}
++
++ {{ if site.Params.debug }}
++ <div class="debug">[leaving {{ templates.Current.Filename }}]</div>
++ {{ end }}
++{{ end }}
++```
++
++### Call stack
++
++To display the chain of templates that led to the current one, create a partial template that iterates through its ancestors:
++
++```go-html-template {file="layouts/partials/template-call-stack.html" copy=true}
++{{ with templates.Current }}
++ <div class="debug">
++ {{ range .Ancestors }}
++ {{ .Filename }}<br>
++ {{ with .Base }}
++ {{ .Filename }}<br>
++ {{ end }}
++ {{ end }}
++ </div>
++{{ end }}
++```
++
++Then call the partial from any template:
++
++```go-html-template {file="layouts/partials/footer/copyright.html" copy=true}
++{{ if site.Params.debug }}
++ {{ partial "template-call-stack.html" . }}
++{{ end }}
++```
++
++The rendered template stack would look something like this:
++
++```text
++/home/user/project/layouts/partials/footer/copyright.html
++/home/user/project/themes/foo/layouts/partials/footer.html
++/home/user/project/layouts/_default/single.html
++/home/user/project/themes/foo/layouts/_default/baseof.html
++```
++
++To reverse the order of the entries, chain the `Reverse` method to the `Ancestors` method:
++
++```go-html-template {file="layouts/partials/template-call-stack.html" copy=true}
++{{ with templates.Current }}
++ <div class="debug">
++ {{ range .Ancestors.Reverse }}
++ {{ with .Base }}
++ {{ .Filename }}<br>
++ {{ end }}
++ {{ .Filename }}<br>
++ {{ end }}
++ </div>
++{{ end }}
++```
++
++### VS Code
++
++To render links that, when clicked, will open the template in Microsoft Visual Studio Code, create a partial template with anchor elements that use the `vscode` URI scheme:
++
++```go-html-template {file="layouts/partials/template-open-in-vs-code.html" copy=true}
++{{ with templates.Current.Parent }}
++ <div class="debug">
++ <a href="vscode://file/{{ .Filename }}">{{ .Name }}</a>
++ {{ with .Base }}
++ <a href="vscode://file/{{ .Filename }}">{{ .Name }}</a>
++ {{ end }}
++ </div>
++{{ end }}
++```
++
++Then call the partial from any template:
++
++```go-html-template {file="layouts/_default/single.html" copy=true}
++{{ define "main" }}
++ <h1>{{ .Title }}</h1>
++ {{ .Content }}
++
++ {{ if site.Params.debug }}
++ {{ partial "template-open-in-vs-code.html" . }}
++ {{ end }}
++{{ end }}
++```
++
++Use the same approach to render the entire call stack as links:
++
++```go-html-template {file="layouts/partials/template-call-stack.html" copy=true}
++{{ with templates.Current }}
++ <div class="debug">
++ {{ range .Ancestors }}
++ <a href="vscode://file/{{ .Filename }}">{{ .Filename }}</a><br>
++ {{ with .Base }}
++ <a href="vscode://file/{{ .Filename }}">{{ .Filename }}</a><br>
++ {{ end }}
++ {{ end }}
++ </div>
++{{ end }}
++```
--- /dev/null
--- /dev/null
++---
++title: time.In
++description: Returns the given date/time as represented in the specified IANA time zone.
++categories: []
++keywords: []
++params:
++ functions_and_methods:
++ aliases: []
++ returnType: time.Time
++ signatures: [time.In TIMEZONE INPUT]
++---
++
++{{< new-in 0.146.0 />}}
++
++The `time.In` function returns the given date/time as represented in the specified [IANA](g) time zone.
++
++- If the time zone is an empty string or `UTC`, the time is returned in [UTC](g).
++- If the time zone is `Local`, the time is returned in the system's local time zone.
++- Otherwise, the time zone must be a valid IANA [time zone name].
++
++[time zone name]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
++
++```go-html-template
++{{ $layout := "2006-01-02T15:04:05-07:00" }}
++{{ $t := time.AsTime "2025-03-31T14:45:00-00:00" }}
++
++{{ $t | time.In "America/Denver" | time.Format $layout }} → 2025-03-31T08:45:00-06:00
++{{ $t | time.In "Australia/Adelaide" | time.Format $layout }} → 2025-04-01T01:15:00+10:30
++{{ $t | time.In "Europe/Oslo" | time.Format $layout }} → 2025-03-31T16:45:00+02:00
++```
--- /dev/null
- ## Options
+---
+title: transform.Unmarshal
+description: Parses serialized data and returns a map or an array. Supports CSV, JSON, TOML, YAML, and XML.
+categories: []
+keywords: []
+params:
+ functions_and_methods:
+ aliases: [unmarshal]
+ returnType: any
+ signatures: ['transform.Unmarshal [OPTIONS] INPUT']
+aliases: [/functions/transform.unmarshal]
+---
+
+The input can be a string or a [resource](g).
+
+## Unmarshal a string
+
+```go-html-template
+{{ $string := `
+title: Les Misérables
+author: Victor Hugo
+`}}
+
+{{ $book := unmarshal $string }}
+{{ $book.title }} → Les Misérables
+{{ $book.author }} → Victor Hugo
+```
+
+## Unmarshal a resource
+
+Use the `transform.Unmarshal` function with global, page, and remote resources.
+
+### Global resource
+
+A global resource is a file within the `assets` directory, or within any directory mounted to the `assets` directory.
+
+```text
+assets/
+└── data/
+ └── books.json
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $path := "data/books.json" }}
+{{ with resources.Get $path }}
+ {{ with . | transform.Unmarshal }}
+ {{ $data = . }}
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get global resource %q" $path }}
+{{ end }}
+
+{{ range where $data "author" "Victor Hugo" }}
+ {{ .title }} → Les Misérables
+{{ end }}
+```
+
+### Page resource
+
+A page resource is a file within a [page bundle].
+
+```text
+content/
+├── post/
+│ └── book-reviews/
+│ ├── books.json
+│ └── index.md
+└── _index.md
+```
+
+```go-html-template
+{{ $data := dict }}
+{{ $path := "books.json" }}
+{{ with .Resources.Get $path }}
+ {{ with . | transform.Unmarshal }}
+ {{ $data = . }}
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get page resource %q" $path }}
+{{ end }}
+
+{{ range where $data "author" "Victor Hugo" }}
+ {{ .title }} → Les Misérables
+{{ end }}
+```
+
+### Remote resource
+
+A remote resource is a file on a remote server, accessible via HTTP or HTTPS.
+
+```go-html-template
+{{ $data := dict }}
+{{ $url := "https://example.org/books.json" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+
+{{ range where $data "author" "Victor Hugo" }}
+ {{ .title }} → Les Misérables
+{{ end }}
+```
+
+> [!note]
+> When retrieving remote data, a misconfigured server may send a response header with an incorrect [Content-Type]. For example, the server may set the Content-Type header to `application/octet-stream` instead of `application/json`.
+>
+> In these cases, pass the resource `Content` through the `transform.Unmarshal` function instead of passing the resource itself. For example, in the above, do this instead:
+>
+> `{{ $data = .Content | transform.Unmarshal }}`
+
- : (`string`) The delimiter used, default is `,`.
++## Working with CSV
++
++### Options
+
+When unmarshaling a CSV file, provide an optional map of options.
+
+delimiter
- {{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }}
++: (`string`) The delimiter used. Default is `,`.
+
+comment
+: (`string`) The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.
+
+lazyQuotes
+: {{< new-in 0.122.0 />}}
+: (`bool`) Whether to allow a quote in an unquoted field, or to allow a non-doubled quote in a quoted field. Default is `false`.
+
++targetType
++: {{< new-in 0.146.7 />}}
++: (`string`) The target data type, either `slice` or `map`. Default is `slice`.
++
++### Examples
++
++The examples below use this CSV file:
++
++```csv
++"name","type","breed","age"
++"Spot","dog","Collie",3
++"Rover","dog","Boxer",5
++"Felix","cat","Calico",7
++```
++
++To render an HTML table from a CSV file:
++
+```go-html-template
++{{ $data := slice }}
++{{ $file := "pets.csv" }}
++{{ with or (.Resources.Get $file) (resources.Get $file) }}
++ {{ $opts := dict "targetType" "slice" }}
++ {{ $data = transform.Unmarshal $opts . }}
++{{ end }}
++
++{{ with $data }}
++ <table>
++ <thead>
++ <tr>
++ {{ range index . 0 }}
++ <th>{{ . }}</th>
++ {{ end }}
++ </tr>
++ </thead>
++ <tbody>
++ {{ range . | after 1 }}
++ <tr>
++ {{ range . }}
++ <td>{{ . }}</td>
++ {{ end }}
++ </tr>
++ {{ end }}
++ </tbody>
++ </table>
++{{ end }}
++```
++
++To extract a subset of the data, or to sort the data, unmarshal to a map instead of a slice:
++
++```go-html-template
++{{ $data := slice }}
++{{ $file := "pets.csv" }}
++{{ with or (.Resources.Get $file) (resources.Get $file) }}
++ {{ $opts := dict "targetType" "map" }}
++ {{ $data = transform.Unmarshal $opts . }}
++{{ end }}
++
++{{ with sort (where $data "type" "dog") "name" "asc" }}
++ <table>
++ <thead>
++ <tr>
++ <th>name</th>
++ <th>type</th>
++ <th>breed</th>
++ <th>age</th>
++ </tr>
++ </thead>
++ <tbody>
++ {{ range . }}
++ <tr>
++ <td>{{ .name }}</td>
++ <td>{{ .type }}</td>
++ <td>{{ .breed }}</td>
++ <td>{{ .age }}</td>
++ </tr>
++ {{ end }}
++ </tbody>
++ </table>
++{{ end }}
+```
+
+## Working with XML
+
+When unmarshaling an XML file, do not include the root node when accessing data. For example, after unmarshaling the RSS feed below, access the feed title with `$data.channel.title`.
+
+```xml
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
+ <channel>
+ <title>Books on Example Site</title>
+ <link>https://example.org/books/</link>
+ <description>Recent content in Books on Example Site</description>
+ <language>en-US</language>
+ <atom:link href="https://example.org/books/index.xml" rel="self" type="application/rss+xml" />
+ <item>
+ <title>The Hunchback of Notre Dame</title>
+ <description>Written by Victor Hugo</description>
+ <link>https://example.org/books/the-hunchback-of-notre-dame/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:12 -0700</pubDate>
+ <guid>https://example.org/books/the-hunchback-of-notre-dame/</guid>
+ </item>
+ <item>
+ <title>Les Misérables</title>
+ <description>Written by Victor Hugo</description>
+ <link>https://example.org/books/les-miserables/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:11 -0700</pubDate>
+ <guid>https://example.org/books/les-miserables/</guid>
+ </item>
+ </channel>
+</rss>
+```
+
+Get the remote data:
+
+```go-html-template
+{{ $data := dict }}
+{{ $url := "https://example.org/books/index.xml" }}
+{{ with try (resources.GetRemote $url) }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else with .Value }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+ {{ end }}
+{{ end }}
+```
+
+Inspect the data structure:
+
+```go-html-template
+<pre>{{ debug.Dump $data }}</pre>
+```
+
+List the book titles:
+
+```go-html-template
+{{ with $data.channel.item }}
+ <ul>
+ {{ range . }}
+ <li>{{ .title }}</li>
+ {{ end }}
+ </ul>
+{{ end }}
+```
+
+Hugo renders this to:
+
+```html
+<ul>
+ <li>The Hunchback of Notre Dame</li>
+ <li>Les Misérables</li>
+</ul>
+```
+
+### XML attributes and namespaces
+
+Let's add a `lang` attribute to the `title` nodes of our RSS feed, and a namespaced node for the ISBN number:
+
+```xml
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<rss version="2.0"
+ xmlns:atom="http://www.w3.org/2005/Atom"
+ xmlns:isbn="http://schemas.isbn.org/ns/1999/basic.dtd"
+>
+ <channel>
+ <title>Books on Example Site</title>
+ <link>https://example.org/books/</link>
+ <description>Recent content in Books on Example Site</description>
+ <language>en-US</language>
+ <atom:link href="https://example.org/books/index.xml" rel="self" type="application/rss+xml" />
+ <item>
+ <title lang="en">The Hunchback of Notre Dame</title>
+ <description>Written by Victor Hugo</description>
+ <isbn:number>9780140443530</isbn:number>
+ <link>https://example.org/books/the-hunchback-of-notre-dame/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:12 -0700</pubDate>
+ <guid>https://example.org/books/the-hunchback-of-notre-dame/</guid>
+ </item>
+ <item>
+ <title lang="fr">Les Misérables</title>
+ <description>Written by Victor Hugo</description>
+ <isbn:number>9780451419439</isbn:number>
+ <link>https://example.org/books/les-miserables/</link>
+ <pubDate>Mon, 09 Oct 2023 09:27:11 -0700</pubDate>
+ <guid>https://example.org/books/les-miserables/</guid>
+ </item>
+ </channel>
+</rss>
+```
+
+After retrieving the remote data, inspect the data structure:
+
+```go-html-template
+<pre>{{ debug.Dump $data }}</pre>
+```
+
+Each item node looks like this:
+
+```json
+{
+ "description": "Written by Victor Hugo",
+ "guid": "https://example.org/books/the-hunchback-of-notre-dame/",
+ "link": "https://example.org/books/the-hunchback-of-notre-dame/",
+ "number": "9780140443530",
+ "pubDate": "Mon, 09 Oct 2023 09:27:12 -0700",
+ "title": {
+ "#text": "The Hunchback of Notre Dame",
+ "-lang": "en"
+ }
+}
+```
+
+The title keys do not begin with an underscore or a letter---they are not valid [identifiers](g). Use the [`index`] function to access the values:
+
+```go-html-template
+{{ with $data.channel.item }}
+ <ul>
+ {{ range . }}
+ {{ $title := index .title "#text" }}
+ {{ $lang := index .title "-lang" }}
+ {{ $ISBN := .number }}
+ <li>{{ $title }} ({{ $lang }}) {{ $ISBN }}</li>
+ {{ end }}
+ </ul>
+{{ end }}
+```
+
+Hugo renders this to:
+
+```html
+<ul>
+ <li>The Hunchback of Notre Dame (en) 9780140443530</li>
+ <li>Les Misérables (fr) 9780451419439</li>
+</ul>
+```
+
+[`index`]: /functions/collections/indexfunction/
+[Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
+[page bundle]: /content-management/page-bundles/
--- /dev/null
+---
+title: Host on GitHub Pages
+description: Host your site on GitHub Pages.
+categories: []
+keywords: []
+aliases: [/hosting-and-deployment/hosting-on-github/]
+---
+
+## Prerequisites
+
+Please complete the following tasks before continuing:
+
+1. [Create a GitHub account]
+1. [Install Git]
+1. [Create a Hugo site] and test it locally with `hugo server`.
+
+## Types of sites
+
+There are three types of GitHub Pages sites: project, user, and organization. Project sites are connected to a specific project hosted on GitHub. User and organization sites are connected to a specific account on GitHub.com.
+
+> [!note]
+> See the [GitHub Pages documentation] to understand the requirements for repository ownership and naming.
+
+## Procedure
+
+### Step 1
+
+Create a GitHub repository.
+
+### Step 2
+
+Push your local repository to GitHub.
+
+### Step 3
+
+Visit your GitHub repository. From the main menu choose **Settings** > **Pages**. In the center of your screen you will see this:
+
+
+{style="max-width: 280px"}
+
+### Step 4
+
+Change the **Source** to `GitHub Actions`. The change is immediate; you do not have to press a Save button.
+
+
+{style="max-width: 280px"}
+
+### Step 5
+
+In your site configuration, change the location of the image cache to the [`cacheDir`] as shown below:
+
+{{< code-toggle file=hugo >}}
+[caches.images]
+dir = ":cacheDir/images"
+{{< /code-toggle >}}
+
+See [configure file caches] for more information.
+
+### Step 6
+
+Create a file named `hugo.yaml` in a directory named `.github/workflows`.
+
+```text
+mkdir -p .github/workflows
+touch .github/workflows/hugo.yaml
+```
+
+### Step 7
+
+> [!note]
+> The workflow below ensures Hugo's `cacheDir` is persistent, preserving modules, processed images, and [`resources.GetRemote`] data between builds.
+
+Copy and paste the YAML below into the file you created. Change the branch name and Hugo version as needed.
+
+```yaml {file=".github/workflows/hugo.yaml" copy=true}
+# Sample workflow for building and deploying a Hugo site to GitHub Pages
+name: Deploy Hugo site to Pages
+
+on:
+ # Runs on pushes targeting the default branch
+ push:
+ branches:
+ - main
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+# Default to bash
+defaults:
+ run:
+ shell: bash
+
+jobs:
+ # Build job
+ build:
+ runs-on: ubuntu-latest
+ env:
+ HUGO_VERSION: 0.145.0
+ HUGO_ENVIRONMENT: production
+ TZ: America/Los_Angeles
+ steps:
+ - name: Install Hugo CLI
+ run: |
+ wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
+ && sudo dpkg -i ${{ runner.temp }}/hugo.deb
+ - name: Install Dart Sass
+ run: sudo snap install dart-sass
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - name: Setup Pages
+ id: pages
+ uses: actions/configure-pages@v5
+ - name: Install Node.js dependencies
+ run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
+ - name: Cache Restore
+ id: cache-restore
+ uses: actions/cache/restore@v4
+ with:
+ path: |
+ ${{ runner.temp }}/hugo_cache
+ key: hugo-${{ github.run_id }}
+ restore-keys:
+ hugo-
++ - name: Configure Git
++ run: git config core.quotepath false
+ - name: Build with Hugo
+ run: |
+ hugo \
+ --gc \
+ --minify \
+ --baseURL "${{ steps.pages.outputs.base_url }}/" \
+ --cacheDir "${{ runner.temp }}/hugo_cache"
+ - name: Cache Save
+ id: cache-save
+ uses: actions/cache/save@v4
+ with:
+ path: |
+ ${{ runner.temp }}/hugo_cache
+ key: ${{ steps.cache-restore.outputs.cache-primary-key }}
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ./public
+
+ # Deployment job
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
+```
+
+### Step 8
+
+Commit and push the change to your GitHub repository.
+
+```sh
+git add -A
+git commit -m "Create hugo.yaml"
+git push
+```
+
+### Step 9
+
+From GitHub's main menu, choose **Actions**. You will see something like this:
+
+
+{style="max-width: 350px"}
+
+### Step 10
+
+When GitHub has finished building and deploying your site, the color of the status indicator will change to green.
+
+
+{style="max-width: 350px"}
+
+### Step 11
+
+Click on the commit message as shown above. You will see this:
+
+
+{style="max-width: 611px"}
+
+Under the deploy step, you will see a link to your live site.
+
+In the future, whenever you push a change from your local repository, GitHub will rebuild your site and deploy the changes.
+
+## Customize the workflow
+
+The example workflow above includes this step, which typically takes 10‑15 seconds:
+
+```yaml
+- name: Install Dart Sass
+ run: sudo snap install dart-sass
+```
+
+You may remove this step if your site, themes, and modules do not transpile Sass to CSS using the [Dart Sass] transpiler.
+
+## Other resources
+
+- [Learn more about GitHub Actions](https://docs.github.com/en/actions)
+- [Caching dependencies to speed up workflows](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows)
+- [Manage a custom domain for your GitHub Pages site](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages)
+
+[Create a GitHub account]: https://github.com/signup
+[Create a Hugo site]: /getting-started/quick-start/
+[Dart Sass]: /functions/css/sass/#dart-sass
+[GitHub Pages documentation]: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites
+[Install Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
+[`cacheDir`]: /configuration/all/#cachedir
+[`resources.GetRemote`]: /functions/resources/getremote/
+[configure file caches]: /configuration/caches/
--- /dev/null
- DART_SASS_VERSION: 1.85.0
+---
+title: Host on GitLab Pages
+description: Host your site on GitLab Pages.
+categories: []
+keywords: []
+aliases: [/hosting-and-deployment/hosting-on-gitlab/]
+---
+
+## Assumptions
+
+- Working familiarity with Git for version control
+- Completion of the Hugo [Quick Start]
+- A [GitLab account](https://gitlab.com/users/sign_in)
+- A Hugo website on your local machine that you are ready to publish
+
+## BaseURL
+
+The `baseURL` in your [site configuration](/configuration/) must reflect the full URL of your GitLab pages repository if you are using the default GitLab Pages URL (e.g., `https://<YourUsername>.gitlab.io/<your-hugo-site>/`) and not a custom domain.
+
+## Configure GitLab CI/CD
+
+Define your [CI/CD](g) jobs by creating a `.gitlab-ci.yml` file in the root of your project.
+
+```yaml {file=".gitlab-ci.yml" copy=true}
+variables:
- HUGO_VERSION: 0.144.2
- NODE_VERSION: 23.x
++ DART_SASS_VERSION: 1.87.0
+ GIT_DEPTH: 0
+ GIT_STRATEGY: clone
+ GIT_SUBMODULE_STRATEGY: recursive
- name: golang:1.23.4-bookworm
++ HUGO_VERSION: 0.146.7
++ NODE_VERSION: 22.x
+ TZ: America/Los_Angeles
+image:
++ name: golang:1.24.2-bookworm
+
+pages:
+ script:
+ # Install brotli
+ - apt-get update
+ - apt-get install -y brotli
+ # Install Dart Sass
+ - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
+ - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz
+ - cp -r dart-sass/ /usr/local/bin
+ - rm -rf dart-sass*
+ - export PATH=/usr/local/bin/dart-sass:$PATH
+ # Install Hugo
+ - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ - apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb
+ # Install Node.js
+ - curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash -
+ - apt-get install -y nodejs
+ # Install Node.js dependencies
+ - "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
++ # Configure Git
++ - git config core.quotepath false
+ # Build
+ - hugo --gc --minify --baseURL ${CI_PAGES_URL}
+ # Compress
+ - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec gzip -f -k {} \;
+ - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec brotli -f -k {} \;
+ artifacts:
+ paths:
+ - public
+ rules:
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+```
+
+## Push your Hugo website to GitLab
+
+Next, create a new repository on GitLab. It is *not* necessary to make the repository public. In addition, you might want to add `/public` to your .gitignore file, as there is no need to push compiled assets to GitLab or keep your output website in version control.
+
+```sh
+# initialize new git repository
+git init
+
+# add /public directory to our .gitignore file
+echo "/public" >> .gitignore
+
+# commit and push code to master branch
+git add .
+git commit -m "Initial commit"
+git remote add origin https://gitlab.com/YourUsername/your-hugo-site.git
+git push -u origin master
+```
+
+## Wait for your page to build
+
+That's it! You can now follow the CI agent building your page at `https://gitlab.com/<YourUsername>/<your-hugo-site>/pipelines`.
+
+After the build has passed, your new website is available at `https://<YourUsername>.gitlab.io/<your-hugo-site>/`.
+
+## Next steps
+
+GitLab supports using custom CNAME's and TLS certificates. For more details on GitLab Pages, see the [GitLab Pages setup documentation](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/).
+
+[Quick Start]: /getting-started/quick-start/
--- /dev/null
- HUGO_VERSION = "0.144.2"
+---
+title: Host on Netlify
+description: Host your site on Netlify.
+categories: []
+keywords: []
+aliases: [/hosting-and-deployment/hosting-on-netlify/]
+---
+
+## Prerequisites
+
+Please complete the following tasks before continuing:
+
+1. [Create a Netlify account]
+1. [Install Git]
+1. [Create a Hugo site] and test it locally with `hugo server`
+1. Commit the changes to your local repository
+1. Push the local repository to your [GitHub], [GitLab], or [Bitbucket] account
+
+[Bitbucket]: https://bitbucket.org/product
+[Create a Hugo site]: /getting-started/quick-start/
+[Create a Netlify account]: https://app.netlify.com/signup
+[GitHub]: https://github.com
+[GitLab]: https://about.gitlab.com/
+[Install Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
+
+## Procedure
+
+This procedure will enable continuous deployment from a GitHub repository. The procedure is essentially the same if you are using GitLab or Bitbucket.
+
+### Step 1
+
+Log in to your Netlify account, navigate to the Sites page, press the **Add new site** button, and choose "Import an existing project" from the dropdown menu.
+
+### Step 2
+
+Select your deployment method.
+
+ 
+
+### Step 3
+
+Authorize Netlify to connect with your GitHub account by pressing the **Authorize Netlify** button.
+
+
+
+### Step 4
+
+Press the **Configure Netlify on GitHub** button.
+
+
+
+### Step 5
+
+Install the Netlify app by selecting your GitHub account.
+
+
+
+### Step 6
+
+Press the **Install** button.
+
+
+
+### Step 7
+
+Click on the site's repository from the list.
+
+
+
+### Step 8
+
+Set the site name and branch from which to deploy.
+
+
+
+### Step 9
+
+Define the build settings, press the **Add environment variables** button, then press the **New variable** button.
+
+
+
+### Step 10
+
+Create a new environment variable named `HUGO_VERSION` and set the value to the [latest version].
+
+[latest version]: https://github.com/gohugoio/hugo/releases/latest
+
+
+
+### Step 11
+
+Press the "Deploy my new site" button at the bottom of the page.
+
+
+
+### Step 12
+
+At the bottom of the screen, wait for the deploy to complete, then click on the deploy log entry.
+
+
+
+### Step 13
+
+Press the **Open production deploy** button to view the live site.
+
+
+
+## Configuration file
+
+In the procedure above we configured our site using the Netlify user interface. Most site owners find it easier to use a configuration file checked into source control.
+
+Create a new file named netlify.toml in the root of your project directory. In its simplest form, the configuration file might look like this:
+
+```toml {file="netlify.toml"}
+[build.environment]
- command = "hugo --gc --minify"
++GO_VERSION = "1.24"
++HUGO_VERSION = "0.146.7"
+NODE_VERSION = "22"
+TZ = "America/Los_Angeles"
+
+[build]
+publish = "public"
- HUGO_VERSION = "0.144.2"
- DART_SASS_VERSION = "1.85.0"
++command = "git config core.quotepath false && hugo --gc --minify"
+```
+
+If your site requires Dart Sass to transpile Sass to CSS, the configuration file should look something like this:
+
+```toml {file="netlify.toml"}
+[build.environment]
++DART_SASS_VERSION = "1.87.0"
++GO_VERSION = "1.24"
++HUGO_VERSION = "0.146.7"
+NODE_VERSION = "22"
+TZ = "America/Los_Angeles"
+
+[build]
+publish = "public"
+command = """\
+ curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ rm dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \
+ export PATH=/opt/build/repo/dart-sass:$PATH && \
++ git config core.quotepath false && \
+ hugo --gc --minify \
+ """
+```
--- /dev/null
- To enable or revoke access to removable media:
+---
+title: Linux
+description: Install Hugo on Linux.
+categories: []
+keywords: []
+weight: 20
+---
+
+## Editions
+
+{{% include "/_common/installation/01-editions.md" %}}
+
+Unless your specific deployment needs require the extended/deploy edition, we recommend the extended edition.
+
+{{% include "/_common/installation/02-prerequisites.md" %}}
+
+{{% include "/_common/installation/03-prebuilt-binaries.md" %}}
+
+## Package managers
+
+### Snap
+
+[Snap] is a free and open-source package manager for Linux. Available for [most distributions], snap packages are simple to install and are automatically updated.
+
+The Hugo snap package is [strictly confined]. Strictly confined snaps run in complete isolation, up to a minimal access level that's deemed always safe. The sites you create and build must be located within your home directory, or on removable media.
+
+To install the extended edition of Hugo:
+
+```sh
+sudo snap install hugo
+```
+
- To enable or revoke access to SSH keys:
++To control automatic updates:
+
+```sh
++# disable automatic updates
++sudo snap refresh --hold hugo
++
++# enable automatic updates
++sudo snap refresh --unhold hugo
++```
++
++To control access to removable media:
++
++```sh
++# allow access
+sudo snap connect hugo:removable-media
++
++# revoke access
+sudo snap disconnect hugo:removable-media
+```
+
++To control access to SSH keys:
+
+```sh
++# allow access
+sudo snap connect hugo:ssh-keys
++
++# revoke access
+sudo snap disconnect hugo:ssh-keys
+```
+
+{{% include "/_common/installation/homebrew.md" %}}
+
+## Repository packages
+
+Most Linux distributions maintain a repository for commonly installed applications.
+
+> [!note]
+> The Hugo version available in package repositories varies based on Linux distribution and release, and in some cases will not be the [latest version].
+>
+> Use one of the other installation methods if your package repository does not provide the desired version.
+
+### Alpine Linux
+
+To install the extended edition of Hugo on [Alpine Linux]:
+
+```sh
+doas apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community hugo
+```
+
+### Arch Linux
+
+Derivatives of the [Arch Linux] distribution of Linux include [EndeavourOS], [Garuda Linux], [Manjaro], and others. To install the extended edition of Hugo:
+
+```sh
+sudo pacman -S hugo
+```
+
+### Debian
+
+Derivatives of the [Debian] distribution of Linux include [elementary OS], [KDE neon], [Linux Lite], [Linux Mint], [MX Linux], [Pop!_OS], [Ubuntu], [Zorin OS], and others. To install the extended edition of Hugo:
+
+```sh
+sudo apt install hugo
+```
+
+You can also download Debian packages from the [latest release] page.
+
+### Exherbo
+
+To install the extended edition of Hugo on [Exherbo]:
+
+1. Add this line to /etc/paludis/options.conf:
+
+ ```text
+ www-apps/hugo extended
+ ```
+
+1. Install using the Paludis package manager:
+
+ ```sh
+ cave resolve -x repository/heirecka
+ cave resolve -x hugo
+ ```
+
+### Fedora
+
+Derivatives of the [Fedora] distribution of Linux include [CentOS], [Red Hat Enterprise Linux], and others. To install the extended edition of Hugo:
+
+```sh
+sudo dnf install hugo
+```
+
+### Gentoo
+
+Derivatives of the [Gentoo] distribution of Linux include [Calculate Linux], [Funtoo], and others. To install the extended edition of Hugo:
+
+1. Specify the `extended` [USE] flag in /etc/portage/package.use/hugo:
+
+ ```text
+ www-apps/hugo extended
+ ```
+
+1. Build using the Portage package manager:
+
+ ```sh
+ sudo emerge www-apps/hugo
+ ```
+
+### NixOS
+
+The NixOS distribution of Linux includes Hugo in its package repository. To install the extended edition of Hugo:
+
+```sh
+nix-env -iA nixos.hugo
+```
+
+### openSUSE
+
+Derivatives of the [openSUSE] distribution of Linux include [GeckoLinux], [Linux Karmada], and others. To install the extended edition of Hugo:
+
+```sh
+sudo zypper install hugo
+```
+
+### Solus
+
+The [Solus] distribution of Linux includes Hugo in its package repository. To install the extended edition of Hugo:
+
+```sh
+sudo eopkg install hugo
+```
+
+### Void Linux
+
+To install the extended edition of Hugo on [Void Linux]:
+
+```sh
+sudo xbps-install -S hugo
+```
+
+{{% include "/_common/installation/04-build-from-source.md" %}}
+
+## Comparison
+
+||Prebuilt binaries|Package managers|Repository packages|Build from source
+:--|:--:|:--:|:--:|:--:
+Easy to install?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:
+Easy to upgrade?|:heavy_check_mark:|:heavy_check_mark:|varies|:heavy_check_mark:
+Easy to downgrade?|:heavy_check_mark:|:heavy_check_mark: [^1]|varies|:heavy_check_mark:
+Automatic updates?|:x:|varies [^2]|:x:|:x:
+Latest version available?|:heavy_check_mark:|:heavy_check_mark:|varies|:heavy_check_mark:
+
+[^1]: Easy if a previous version is still installed.
+[^2]: Snap packages are automatically updated. Homebrew requires advanced configuration.
+
+[Alpine Linux]: https://alpinelinux.org/
+[Arch Linux]: https://archlinux.org/
+[Calculate Linux]: https://www.calculate-linux.org/
+[CentOS]: https://www.centos.org/
+[Debian]: https://www.debian.org/
+[elementary OS]: https://elementary.io/
+[EndeavourOS]: https://endeavouros.com/
+[Exherbo]: https://www.exherbolinux.org/
+[Fedora]: https://getfedora.org/
+[Funtoo]: https://www.funtoo.org/
+[Garuda Linux]: https://garudalinux.org/
+[GeckoLinux]: https://geckolinux.github.io/
+[Gentoo]: https://www.gentoo.org/
+[KDE neon]: https://neon.kde.org/
+[latest version]: https://github.com/gohugoio/hugo/releases/latest
+[Linux Karmada]: https://linuxkamarada.com/
+[Linux Lite]: https://www.linuxliteos.com/
+[Linux Mint]: https://linuxmint.com/
+[Manjaro]: https://manjaro.org/
+[most distributions]: https://snapcraft.io/docs/installing-snapd
+[MX Linux]: https://mxlinux.org/
+[openSUSE]: https://www.opensuse.org/
+[Pop!_OS]: https://pop.system76.com/
+[Red Hat Enterprise Linux]: https://www.redhat.com/
+[Snap]: https://snapcraft.io/
+[Solus]: https://getsol.us/
+[strictly confined]: https://snapcraft.io/docs/snap-confinement
+[Ubuntu]: https://ubuntu.com/
+[USE]: https://packages.gentoo.org/packages/www-apps/hugo
+[Void Linux]: https://voidlinux.org/
+[Zorin OS]: https://zorin.com/os/
--- /dev/null
- "path" .name
+{{/* Get releases from GitHub. */}}
+{{ $u := "https://api.github.com/repos/gohugoio/hugo/releases" }}
+{{ $releases := partial "helpers/funcs/get-remote-data.html" $u }}
+{{ $releases = where $releases "draft" false }}
+{{ $releases = where $releases "prerelease" false }}
+
+{{/* Add pages. */}}
+{{ range $releases | first 24 }}
+ {{ $publishDate := .published_at | time.AsTime }}
+
+ {{/* Correct the v0.138.0 release date. See https://github.com/gohugoio/hugo/issues/13066. */}}
+ {{ if eq .name "v0.138.0" }}
+ {{ $publishDate = "2024-11-06T11:22:34Z" }}
+ {{ end }}
+
+ {{ $content := dict "mediaType" "text/markdown" "value" "" }}
+ {{ $dates := dict "publishDate" (time.AsTime $publishDate) }}
+ {{ $params := dict "permalink" .html_url }}
+ {{ $build := dict "render" "never" "list" "local" }}
+ {{ $page := dict
+ "build" $build
+ "content" $content
+ "dates" $dates
+ "kind" "page"
+ "params" $params
++ "path" (strings.Replace .name "." "-")
++ "slug" .name
+ "title" (printf "Release %s" .name)
+ }}
+ {{ $.AddPage $page }}
+{{ end }}
--- /dev/null
--- /dev/null
++---
++title: IANA
++reference: https://www.iana.org/about
++---
++
++_IANA_ is an abbreviation for the Internet Assigned Numbers Authority, a non-profit organization that manages the allocation of global IP addresses, autonomous system numbers, DNS root zone, media types, and other Internet Protocol-related resources.
--- /dev/null
--- /dev/null
++---
++title: UTC
++reference: https://en.wikipedia.org/wiki/Coordinated_Universal_Time
++---
++
++_UTC_ is an abbreviation for Coordinated Universal Time, the primary time standard used worldwide to regulate clocks and time. It is the basis for civil time and time zones across the globe.
--- /dev/null
- > When working with the Markdown [content format], this shortcode has become largely redundant. Its functionality is now primarily handled by [link render hooks], specifically the embedded one provided by Hugo. This hook effectively addresses all the use cases previously covered by this shortcode.
+---
+title: Ref shortcode
+linkTitle: Ref
+description: Insert a permalink to the given page reference using the ref shortcode.
+categories: []
+keywords: []
+---
+
+> [!note]
+> To override Hugo's embedded `ref` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+> [!note]
- [link render hooks]: /render-hooks/images/#default
++> When working with Markdown, this shortcode is obsolete. Instead, use a [link render hook] that resolves the link destination using the `GetPage` method on the `Page` object. You can either create your own, or simply enable the [embedded link render hook]. The embedded link render hook is automatically enabled for multilingual single-host projects.
+
+## Usage
+
+The `ref` shortcode accepts either a single positional argument (the path) or one or more named arguments, as listed below.
+
+## Arguments
+
+{{% include "_common/ref-and-relref-options.md" %}}
+
+## Examples
+
+The `ref` shortcode typically provides the destination for a Markdown link.
+
+> [!note]
+> Always use [Markdown notation] notation when calling this shortcode.
+
+The following examples show the rendered output for a page on the English version of the site:
+
+```md
+[Link A]({{%/* ref "/books/book-1" */%}})
+
+[Link B]({{%/* ref path="/books/book-1" */%}})
+
+[Link C]({{%/* ref path="/books/book-1" lang="de" */%}})
+
+[Link D]({{%/* ref path="/books/book-1" lang="de" outputFormat="json" */%}})
+```
+
+Rendered:
+
+```html
+<a href="https://example.org/en/books/book-1/">Link A</a>
+
+<a href="https://example.org/en/books/book-1/">Link B</a>
+
+<a href="https://example.org/de/books/book-1/">Link C</a>
+
+<a href="https://example.org/de/books/book-1/index.json">Link D</a>
+```
+
+## Error handling
+
+{{% include "_common/ref-and-relref-error-handling.md" %}}
+
+[content format]: /content-management/formats/
- [source code]: {{% eturl ref %}}
++[embedded link render hook]: /render-hooks/links/#default
++[link render hook]: /render-hooks/links/
+[Markdown notation]: /content-management/shortcodes/#notation
++[source code]: {{% eturl relref %}}
--- /dev/null
- > When working with the Markdown [content format], this shortcode has become largely redundant. Its functionality is now primarily handled by [link render hooks], specifically the embedded one provided by Hugo. This hook effectively addresses all the use cases previously covered by this shortcode.
+---
+title: Relref shortcode
+linkTitle: Relref
+description: Insert a relative permalink to the given page reference using the relref shortcode.
+categories: []
+keywords: []
+---
+
+> [!note]
+> To override Hugo's embedded `relref` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+> [!note]
- [link render hooks]: /render-hooks/links/
++> When working with Markdown, this shortcode is obsolete. Instead, use a [link render hook] that resolves the link destination using the `GetPage` method on the `Page` object. You can either create your own, or simply enable the [embedded link render hook]. The embedded link render hook is automatically enabled for multilingual single-host projects.
+
+## Usage
+
+The `relref` shortcode accepts either a single positional argument (the path) or one or more named arguments, as listed below.
+
+## Arguments
+
+{{% include "_common/ref-and-relref-options.md" %}}
+
+## Examples
+
+The `relref` shortcode typically provides the destination for a Markdown link.
+
+> [!note]
+> Always use [Markdown notation] notation when calling this shortcode.
+
+The following examples show the rendered output for a page on the English version of the site:
+
+```md
+[Link A]({{%/* ref "/books/book-1" */%}})
+
+[Link B]({{%/* ref path="/books/book-1" */%}})
+
+[Link C]({{%/* ref path="/books/book-1" lang="de" */%}})
+
+[Link D]({{%/* ref path="/books/book-1" lang="de" outputFormat="json" */%}})
+```
+
+Rendered:
+
+```html
+<a href="/en/books/book-1/">Link A</a>
+
+<a href="/en/books/book-1/">Link B</a>
+
+<a href="/de/books/book-1/">Link C</a>
+
+<a href="/de/books/book-1/index.json">Link D</a>
+```
+
+## Error handling
+
+{{% include "_common/ref-and-relref-error-handling.md" %}}
+
+[content format]: /content-management/formats/
++[embedded link render hook]: /render-hooks/links/#default
++[link render hook]: /render-hooks/links/
+[Markdown notation]: /content-management/shortcodes/#notation
+[source code]: {{% eturl relref %}}
--- /dev/null
- id
- : (`string`) The `id` of the Vimeo video
+---
+title: Vimeo shortcode
+linkTitle: Vimeo
+description: Embed a Vimeo video in your content using the vimeo shortcode.
+categories: []
+keywords: []
+---
+
+> [!note]
+> To override Hugo's embedded `vimeo` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+## Example
+
+To display a Vimeo video with this URL:
+
+```text
+https://vimeo.com/channels/staffpicks/55073825
+```
+
+Include this in your Markdown:
+
+```text
+{{</* vimeo 55073825 */>}}
+```
+
+Hugo renders this to:
+
+{{< vimeo 55073825 >}}
+
+## Arguments
+
++id
++: (string) The video `id`. Optional if the `id` is provided as a positional argument as shown in the example above.
++
++allowFullScreen
++: {{< new-in 0.146.0 />}}
++: (`bool`) Whether the `iframe` element can activate full screen mode. Default is `true`.
++
+class
+: (`string`) The `class` attribute of the wrapping `div` element. Adding one or more CSS classes disables inline styling.
+
- If you provide a `class` or `title` you must use a named parameter for the `id`.
++loading
++: {{< new-in 0.146.0 />}}
++: (`string`) The loading attribute of the `iframe` element, either `eager` or `lazy`. Default is `eager`.
+
+title
+: (`string`) The `title` attribute of the `iframe` element.
+
- {{</* vimeo id=55073825 class="foo bar" title="My Video" */>}}
++Here's an example using some of the available arguments:
+
+```text
++{{</* vimeo id=55073825 allowFullScreen=false loading=lazy */>}}
+```
+
+## Privacy
+
+Adjust the relevant privacy settings in your site configuration.
+
+{{< code-toggle config=privacy.vimeo />}}
+
+disable
+: (`bool`) Whether to disable the shortcode. Default is `false`.
+
+enableDNT
+: (`bool`) Whether to block the Vimeo player from tracking session data and analytics. Default is `false`.
+
+simple
+: (`bool`) Whether to enable simple mode. If `true`, the video thumbnail is fetched from Vimeo and overlaid with a play button. Clicking the thumbnail opens the video in a new Vimeo tab. Default is `false`.
+
+The source code for the simple version of the shortcode is available [here].
+
+[here]: {{% eturl vimeo_simple %}}
+[source code]: {{% eturl vimeo %}}
--- /dev/null
- Example using some of the above:
+---
+title: YouTube shortcode
+linkTitle: YouTube
+description: Embed a YouTube video in your content using the youtube shortcode.
+categories: []
+keywords: []
+---
+
+> [!note]
+> To override Hugo's embedded `youtube` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory.
+
+## Example
+
+To display a YouTube video with this URL:
+
+```text
+https://www.youtube.com/watch?v=0RKpf3rK57I
+```
+
+Include this in your Markdown:
+
+```texts
+{{</* youtube 0RKpf3rK57I */>}}
+```
+
+Hugo renders this to:
+
+{{< youtube 0RKpf3rK57I >}}
+
+## Arguments
+
+id
+: (`string`) The video `id`. Optional if the `id` is provided as a positional argument as shown in the example above.
+
+allowFullScreen
+: {{< new-in 0.125.0 />}}
+: (`bool`) Whether the `iframe` element can activate full screen mode. Default is `true`.
+
+autoplay
+: {{< new-in 0.125.0 />}}
+: (`bool`) Whether to automatically play the video. Forces `mute` to `true`. Default is `false`.
+
+class
+: (`string`) The `class` attribute of the wrapping `div` element. When specified, removes the `style` attributes from the `iframe` element and its wrapping `div` element.
+
+controls
+: {{< new-in 0.125.0 />}}
+: (`bool`) Whether to display the video controls. Default is `true`.
+
+end
+: {{< new-in 0.125.0 />}}
+: (`int`) The time, measured in seconds from the start of the video, when the player should stop playing the video.
+
+loading
+: {{< new-in 0.125.0 />}}
+: (`string`) The loading attribute of the `iframe` element, either `eager` or `lazy`. Default is `eager`.
+
+loop
+: {{< new-in 0.125.0 />}}
+: (`bool`) Whether to indefinitely repeat the video. Ignores the `start` and `end` arguments after the first play. Default is `false`.
+
+mute
+: {{< new-in 0.125.0 />}}
+: (`bool`) Whether to mute the video. Always `true` when `autoplay` is `true`. Default is `false`.
+
+start
+: {{< new-in 0.125.0 />}}
+: (`int`) The time, measured in seconds from the start of the video, when the player should start playing the video.
+
+title
+: (`string`) The `title` attribute of the `iframe` element. Defaults to "YouTube video".
+
++Here's an example using some of the available arguments:
+
+```text
+{{</* youtube id=0RKpf3rK57I start=30 end=60 loading=lazy */>}}
+```
+
+## Privacy
+
+Adjust the relevant privacy settings in your site configuration.
+
+{{< code-toggle config=privacy.youTube />}}
+
+disable
+: (`bool`) Whether to disable the shortcode. Default is `false`.
+
+privacyEnhanced
+: (`bool`) Whether to block YouTube from storing information about visitors on your website unless the user plays the embedded video. Default is `false`.
+
+[source code]: {{% eturl youtube %}}
--- /dev/null
- title: Embedded templates
- description: Hugo provides embedded templates for common use cases.
+---
++title: Embedded partial templates
++description: Hugo provides embedded partial templates for common use cases.
+categories: []
+keywords: []
+weight: 170
+aliases: [/templates/internal]
+---
+
+## Disqus
+
+> [!note]
+> To override Hugo's embedded Disqus template, copy the [source code]({{% eturl disqus %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+>
+> `{{ partial "disqus.html" . }}`
+
+Hugo includes an embedded template for [Disqus], a popular commenting system for both static and dynamic websites. To effectively use Disqus, secure a Disqus "shortname" by [signing up] for the free service.
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/disqus.html" . }}
+```
+
+### Configuration {#configuration-disqus}
+
+To use Hugo's Disqus template, first set up a single configuration value:
+
+{{< code-toggle file=hugo >}}
+[services.disqus]
+shortname = 'your-disqus-shortname'
+{{</ code-toggle >}}
+
+Hugo's Disqus template accesses this value with:
+
+```go-html-template
+{{ .Site.Config.Services.Disqus.Shortname }}
+```
+
+You can also set the following in the front matter for a given piece of content:
+
+- `disqus_identifier`
+- `disqus_title`
+- `disqus_url`
+
+### Privacy {#privacy-disqus}
+
+Adjust the relevant privacy settings in your site configuration.
+
+{{< code-toggle config=privacy.disqus />}}
+
+disable
+: (`bool`) Whether to disable the template. Default is `false`.
+
+## Google Analytics
+
+> [!note]
+> To override Hugo's embedded Google Analytics template, copy the [source code]({{% eturl google_analytics %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+>
+> `{{ partial "google_analytics.html" . }}`
+
+Hugo includes an embedded template supporting [Google Analytics 4].
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/google_analytics.html" . }}
+```
+
+### Configuration {#configuration-google-analytics}
+
+Provide your tracking ID in your configuration file:
+
+{{< code-toggle file=hugo >}}
+[services.googleAnalytics]
+id = "G-MEASUREMENT_ID"
+{{</ code-toggle >}}
+
+To use this value in your own template, access the configured ID with `{{ site.Config.Services.GoogleAnalytics.ID }}`.
+
+### Privacy {#privacy-google-analytics}
+
+Adjust the relevant privacy settings in your site configuration.
+
+{{< code-toggle config=privacy.googleAnalytics />}}
+
+disable
+: (`bool`) Whether to disable the template. Default is `false`.
+
+respectDoNotTrack
+: (`bool`) Whether to respect the browser's "do not track" setting. Default is `false`.
+
+## Open Graph
+
+> [!note]
+> To override Hugo's embedded Open Graph template, copy the [source code]({{% eturl opengraph %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+>
+> `{{ partial "opengraph.html" . }}`
+
+Hugo includes an embedded template for the [Open Graph protocol](https://ogp.me/), metadata that enables a page to become a rich object in a social graph.
+This format is used for Facebook and some other sites.
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/opengraph.html" . }}
+```
+
+### Configuration {#configuration-open-graph}
+
+Hugo's Open Graph template is configured using a mix of configuration settings and [front matter](/content-management/front-matter/) on individual pages.
+
+{{< code-toggle file=hugo >}}
+[params]
+ description = 'Text about my cool site'
+ images = ['site-feature-image.jpg']
+ title = 'My cool site'
+ [params.social]
+ facebook_admin = 'jsmith'
+[taxonomies]
+ series = 'series'
+{{</ code-toggle >}}
+
+{{< code-toggle file=content/blog/my-post.md fm=true >}}
+title = "Post title"
+description = "Text about this post"
+date = 2024-03-08T08:18:11-08:00
+images = ["post-cover.png"]
+audio = []
+videos = []
+series = []
+tags = []
+{{</ code-toggle >}}
+
+Hugo uses the page title and description for the title and description metadata.
+The first 6 URLs from the `images` array are used for image metadata.
+If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata.
+
+Various optional metadata can also be set:
+
+- Date, published date, and last modified data are used to set the published time metadata if specified.
+- `audio` and `videos` are URL arrays like `images` for the audio and video metadata tags, respectively.
+- The first 6 `tags` on the page are used for the tags metadata.
+- The `series` taxonomy is used to specify related "see also" pages by placing them in the same series.
+
+If using YouTube this will produce a og:video tag like `<meta property="og:video" content="url">`. Use the `https://youtu.be/<id>` format with YouTube videos (example: `https://youtu.be/qtIqKaDlqXo`).
+
++## Pagination
++
++See [details](/templates/pagination/).
++
+## Schema
+
+> [!note]
+> To override Hugo's embedded Schema template, copy the [source code]({{% eturl schema %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+>
+> `{{ partial "schema.html" . }}`
+
+Hugo includes an embedded template to render [microdata] `meta` elements within the `head` element of your templates.
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/schema.html" . }}
+```
+
+## X (Twitter) Cards
+
+> [!note]
+> To override Hugo's embedded Twitter Cards template, copy the [source code]({{% eturl twitter_cards %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function:
+>
+> `{{ partial "twitter_cards.html" . }}`
+
+Hugo includes an embedded template for [X (Twitter) Cards](https://developer.x.com/en/docs/twitter-for-websites/cards/overview/abouts-cards),
+metadata used to attach rich media to Tweets linking to your site.
+
+To include the embedded template:
+
+```go-html-template
+{{ template "_internal/twitter_cards.html" . }}
+```
+
+### Configuration {#configuration-x-cards}
+
+Hugo's X (Twitter) Card template is configured using a mix of configuration settings and [front-matter](/content-management/front-matter/) values on individual pages.
+
+{{< code-toggle file=hugo >}}
+[params]
+ images = ["site-feature-image.jpg"]
+ description = "Text about my cool site"
+{{</ code-toggle >}}
+
+{{< code-toggle file=content/blog/my-post.md fm=true >}}
+title = "Post title"
+description = "Text about this post"
+images = ["post-cover.png"]
+{{</ code-toggle >}}
+
+If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata.
+If no image resources with those names are found, the images defined in the [site config](/configuration/) are used instead.
+If no images are found at all, then an image-less Twitter `summary` card is used instead of `summary_large_image`.
+
+Hugo uses the page title and description for the card's title and description fields. The page summary is used if no description is given.
+
+Set the value of `twitter:site` in your site configuration:
+
+{{< code-toggle file=hugo >}}
+[params.social]
+twitter = "GoHugoIO"
+{{</ code-toggle >}}
+
+NOTE: The `@` will be added for you
+
+```html
+<meta name="twitter:site" content="@GoHugoIO"/>
+```
+
+[`partial`]: /functions/partials/include/
+[Disqus]: https://disqus.com
+[Google Analytics 4]: https://support.google.com/analytics/answer/10089681
+[microdata]: https://html.spec.whatwg.org/multipage/microdata.html#microdata
+[signing up]: https://disqus.com/profile/signup/
--- /dev/null
- The second argument in a partial call is the variable being passed down. The above examples are passing the `.`, which tells the template receiving the partial to apply the current [context][context].
+---
+title: Partial templates
+description: Partials are smaller, context-aware components in your list and page templates that can be used economically to keep your templating DRY.
+categories: []
+keywords: []
+weight: 100
+aliases: [/templates/partials/,/layout/chrome/]
+---
+
+{{< youtube pjS4pOLyB7c >}}
+
+## Use partials in your templates
+
+All partials for your Hugo project are located in a single `layouts/partials` directory. For better organization, you can create multiple subdirectories within `partials` as well:
+
+```txt
+layouts/
+└── partials/
+ ├── footer/
+ │ ├── scripts.html
+ │ └── site-footer.html
+ ├── head/
+ │ ├── favicons.html
+ │ ├── metadata.html
+ │ └── prerender.html
+ └── header/
+ ├── site-header.html
+ └── site-nav.html
+```
+
+All partials are called within your templates using the following pattern:
+
+```go-html-template
+{{ partial "<PATH>/<PARTIAL>.html" . }}
+```
+
+> [!note]
+> One of the most common mistakes with new Hugo users is failing to pass a context to the partial call. In the pattern above, note how "the dot" (`.`) is required as the second argument to give the partial context. You can read more about "the dot" in the [Hugo templating introduction](/templates/introduction/#context).
+
+> [!note]
+> Do not include the word "baseof" when naming partial templates. The word "baseof" is reserved for base templates.
+
+As shown in the above example directory structure, you can nest your directories within `partials` for better source organization. You only need to call the nested partial's path relative to the `partials` directory:
+
+```go-html-template
+{{ partial "header/site-header.html" . }}
+{{ partial "footer/scripts.html" . }}
+```
+
+### Variable scoping
+
++The second argument in a partial call is the variable being passed down. The above examples are passing the dot (`.`), which tells the template receiving the partial to apply the current [context][context].
+
+This means the partial will *only* be able to access those variables. The partial is isolated and cannot access the outer scope. From within the partial, `$.Var` is equivalent to `.Var`.
+
+## Returning a value from a partial
+
+In addition to outputting markup, partials can be used to return a value of any type. In order to return a value, a partial must include a lone `return` statement *at the end of the partial*.
+
+### Example GetFeatured
+
+```go-html-template
+{{/* layouts/partials/GetFeatured.html */}}
+{{ return first . (where site.RegularPages "Params.featured" true) }}
+```
+
+```go-html-template
+{{/* layouts/index.html */}}
+{{ range partial "GetFeatured.html" 5 }}
+ [...]
+{{ end }}
+```
+
+### Example GetImage
+
+```go-html-template
+{{/* layouts/partials/GetImage.html */}}
+{{ $image := false }}
+{{ with .Params.gallery }}
+ {{ $image = index . 0 }}
+{{ end }}
+{{ with .Params.image }}
+ {{ $image = . }}
+{{ end }}
+{{ return $image }}
+```
+
+```go-html-template
+{{/* layouts/_default/single.html */}}
+{{ with partial "GetImage.html" . }}
+ [...]
+{{ end }}
+```
+
+> [!note]
+> Only one `return` statement is allowed per partial file.
+
+## Inline partials
+
+You can also define partials inline in the template. But remember that template namespace is global, so you need to make sure that the names are unique to avoid conflicts.
+
+```go-html-template
+Value: {{ partial "my-inline-partial.html" . }}
+
+{{ define "partials/my-inline-partial.html" }}
+{{ $value := 32 }}
+{{ return $value }}
+{{ end }}
+```
+
+## Cached partials
+
+The `partialCached` template function provides significant performance gains for complex templates that don't need to be re-rendered on every invocation. See [details][partialcached].
+
+## Examples
+
+### `header.html`
+
+The following `header.html` partial template is used for [spf13.com](https://spf13.com/):
+
+```go-html-template {file="layouts/partials/header.html"}
+<!DOCTYPE html>
+<html class="no-js" lang="en-US" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
+<head>
+ <meta charset="utf-8">
+
+ {{ partial "meta.html" . }}
+
+ <base href="{{ .Site.BaseURL }}">
+ <title> {{ .Title }} : spf13.com </title>
+ <link rel="canonical" href="{{ .Permalink }}">
+ {{ if .RSSLink }}<link href="{{ .RSSLink }}" rel="alternate" type="application/rss+xml" title="{{ .Title }}" />{{ end }}
+
+ {{ partial "head_includes.html" . }}
+</head>
+```
+
+> [!note]
+> The `header.html` example partial was built before the introduction of block templates to Hugo. Read more on [base templates and blocks](/templates/base/) for defining the outer chrome or shell of your master templates (i.e., your site's head, header, and footer). You can even combine blocks and partials for added flexibility.
+
+### `footer.html`
+
+The following `footer.html` partial template is used for [spf13.com](https://spf13.com/):
+
+```go-html-template {file="layouts/partials/footer.html"}
+<footer>
+ <div>
+ <p>
+ © 2013-14 Steve Francia.
+ <a href="https://creativecommons.org/licenses/by/3.0/" title="Creative Commons Attribution">Some rights reserved</a>;
+ please attribute properly and link back.
+ </p>
+ </div>
+</footer>
+```
+
+[context]: /templates/introduction/
+[partialcached]: /functions/partials/includecached/
--- /dev/null
- [GitHub]: https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates/shortcodes
+---
+title: Shortcode templates
+description: Create custom shortcodes to simplify and standardize content creation.
+categories: []
+keywords: []
+weight: 120
+aliases: [/templates/shortcode-templates/]
+---
+
+> [!note]
+> Before creating custom shortcodes, please review the [shortcodes] page in the [content management] section. Understanding the usage details will help you design and create better templates.
+
+## Introduction
+
+Hugo provides [embedded shortcodes] for many common tasks, but you'll likely need to create your own for more specific needs. Some examples of custom shortcodes you might develop include:
+
+- Audio players
+- Video players
+- Image galleries
+- Diagrams
+- Maps
+- Tables
+- And many other custom elements
+
+## Directory structure
+
+Create shortcode templates within the `layouts/shortcodes` directory, either at its root or organized into subdirectories.
+
+```text
+layouts/
+└── shortcodes/
+ ├── diagrams/
+ │ ├── kroki.html
+ │ └── plotly.html
+ ├── media/
+ │ ├── audio.html
+ │ ├── gallery.html
+ │ └── video.html
+ ├── capture.html
+ ├── column.html
+ ├── include.html
+ └── row.html
+```
+
+When calling a shortcode in a subdirectory, specify its path relative to the `shortcode` directory, excluding the file extension.
+
+```text
+{{</* media/audio path=/audio/podcast/episode-42.mp3 */>}}
+```
+
+## Lookup order
+
+Hugo selects shortcode templates based on the shortcode name, the current output format, and the current language. The examples below are sorted by specificity in descending order. The least specific path is at the bottom of the list.
+
+Shortcode name|Output format|Language|Template path
+:--|:--|:--|:--
+foo|html|en|`layouts/shortcodes/foo.en.html`
+foo|html|en|`layouts/shortcodes/foo.html.html`
+foo|html|en|`layouts/shortcodes/foo.html`
+foo|html|en|`layouts/shortcodes/foo.html.en.html`
+
+Shortcode name|Output format|Language|Template path
+:--|:--|:--|:--
+foo|json|en|`layouts/shortcodes/foo.en.json`
+foo|json|en|`layouts/shortcodes/foo.json`
+foo|json|en|`layouts/shortcodes/foo.json.json`
+foo|json|en|`layouts/shortcodes/foo.json.en.json`
+
+## Methods
+
+Use these methods in your shortcode templates. Refer to each methods's documentation for details and examples.
+
+{{% list-pages-in-section path=/methods/shortcode %}}
+
+## Examples
+
+These examples range in complexity from simple to moderately advanced, with some simplified for clarity.
+
+### Insert year
+
+Create a shortcode to insert the current year:
+
+```go-html-template {file="layouts/shortcodes/year.html"}
+{{- now.Format "2006" -}}
+```
+
+Then call the shortcode from within your markup:
+
+```text {file="content/example.md"}
+This is {{</* year */>}}, and look at how far we've come.
+```
+
+This shortcode can be used inline or as a block on its own line. If a shortcode might be used inline, remove the surrounding [whitespace] by using [template action](g) delimiters with hyphens.
+
+### Insert image
+
+This example assumes the following content structure, where `content/example/index.md` is a [page bundle](g) containing one or more [page resources](g).
+
+```text
+content/
+├── example/
+│ ├── a.jpg
+│ └── index.md
+└── _index.md
+```
+
+Create a shortcode to capture an image as a page resource, resize it to the given width, convert it to the WebP format, and add an `alt` attribute:
+
+```go-html-template {file="layouts/shortcodes/image.html"}
+{{- with .Page.Resources.Get (.Get "path") }}
+ {{- with .Process (printf "resize %dx wepb" ($.Get "width")) -}}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $.Get "alt" }}">
+ {{- end }}
+{{- end -}}
+```
+
+Then call the shortcode from within your markup:
+
+```text {file="content/example/index.md"}
+{{</* image path=a.jpg width=300 alt="A white kitten" */>}}
+```
+
+The example above uses:
+
+- The [`with`] statement to rebind the [context](g) after each successful operation
+- The [`Get`] method to retrieve arguments by name
+- The `$` to access the template context
+
+> [!note]
+> Make sure that you thoroughly understand the concept of context. The most common templating errors made by new users relate to context.
+>
+> Read more about context in the [introduction to templating].
+
+### Insert image with error handling
+
+The previous example, while functional, silently fails if the image is missing, and does not gracefully exit if a required argument is missing. We'll add error handling to address these issues:
+
+```go-html-template {file="layouts/shortcodes/image.html"}
+{{- with .Get "path" }}
+ {{- with $r := $.Page.Resources.Get ($.Get "path") }}
+ {{- with $.Get "width" }}
+ {{- with $r.Process (printf "resize %dx wepb" ($.Get "width" )) }}
+ {{- $alt := or ($.Get "alt") "" -}}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="{{ $alt }}">
+ {{- end }}
+ {{- else }}
+ {{- errorf "The %q shortcode requires a 'width' argument: see %s" $.Name $.Position }}
+ {{- end }}
+ {{- else }}
+ {{- warnf "The %q shortcode was unable to find %s: see %s" $.Name ($.Get "path") $.Position }}
+ {{- end }}
+{{- else }}
+ {{- errorf "The %q shortcode requires a 'path' argument: see %s" .Name .Position }}
+{{- end -}}
+```
+
+This template throws an error and gracefully fails the build if the author neglected to provide a `path` or `width` argument, and it emits a warning if it cannot find the image at the specified path. If the author does not provide an `alt` argument, the `alt` attribute is set to an empty string.
+
+The [`Name`] and [`Position`] methods provide helpful context for errors and warnings. For example, a missing `width` argument causes the shortcode to throw this error:
+
+```text
+ERROR The "image" shortcode requires a 'width' argument: see "/home/user/project/content/example/index.md:7:1"
+```
+
+### Positional arguments
+
+Shortcode arguments can be [named or positional]. We used named arguments previously; let's explore positional arguments. Here's the named argument version of our example:
+
+```text {file="content/example/index.md"}
+{{</* image path=a.jpg width=300 alt="A white kitten" */>}}
+```
+
+Here's how to call it with positional arguments:
+
+```text {file="content/example/index.md"}
+{{</* image a.jpg 300 "A white kitten" */>}}
+```
+
+Using the `Get` method with zero-indexed keys, we'll initialize variables with descriptive names in our template:
+
+```go-html-template {file="layouts/shortcodes/image.html"}
+{{ $path := .Get 0 }}
+{{ $width := .Get 1 }}
+{{ $alt := .Get 2 }}
+```
+
+> [!note]
+> Positional arguments work well for frequently used shortcodes with one or two arguments. Since you'll use them often, the argument order will be easy to remember. For less frequently used shortcodes, or those with more than two arguments, named arguments improve readability and reduce the chance of errors.
+
+### Named and positional arguments
+
+You can create a shortcode that will accept both named and positional arguments, but not at the same time. Use the [`IsNamedParams`] method to determine whether the shortcode call used named or positional arguments:
+
+```go-html-template {file="layouts/shortcodes/image.html"}
+{{ $path := cond (.IsNamedParams) (.Get "path") (.Get 0) }}
+{{ $width := cond (.IsNamedParams) (.Get "width") (.Get 1) }}
+{{ $alt := cond (.IsNamedParams) (.Get "alt") (.Get 2) }}
+```
+
+This example uses the `cond` alias for the [`compare.Conditional`] function to get the argument by name if `IsNamedParams` returns `true`, otherwise get the argument by position.
+
+### Argument collection
+
+Use the [`Params`] method to access the arguments as a collection.
+
+When using named arguments, the `Params` method returns a map:
+
+```text {file="content/example/index.md"}
+{{</* image path=a.jpg width=300 alt="A white kitten" */>}}
+```
+
+```go-html-template {file="layouts/shortcodes/image.html"}
+{{ .Params.path }} → a.jpg
+{{ .Params.width }} → 300
+{{ .Params.alt }} → A white kitten
+```
+
+ When using positional arguments, the `Params` method returns a slice:
+
+```text {file="content/example/index.md"}
+{{</* image a.jpg 300 "A white kitten" */>}}
+```
+
+```go-html-template {file="layouts/shortcodes/image.html"}
+{{ index .Params 0 }} → a.jpg
+{{ index .Params 1 }} → 300
+{{ index .Params 1 }} → A white kitten
+```
+
+Combine the `Params` method with the [`collections.IsSet`] function to determine if a parameter is set, even if its value is falsy.
+
+### Inner content
+
+Extract the content enclosed within shortcode tags using the [`Inner`] method. This example demonstrates how to pass both content and a title to a shortcode. The shortcode then generates a `div` element containing an `h2` element (displaying the title) and the provided content.
+
+```text {file="content/example.md"}
+{{</* contrived title="A Contrived Example" */>}}
+This is a **bold** word, and this is an _emphasized_ word.
+{{</* /contrived */>}}
+```
+
+```go-html-template {file="layouts/shortcodes/contrived.html"}
+<div class="contrived">
+ <h2>{{ .Get "title" }}</h2>
+ {{ .Inner | .Page.RenderString }}
+</div>
+```
+
+The preceding example called the shortcode using [standard notation], requiring us to process the inner content with the [`RenderString`] method to convert the Markdown to HTML. This conversion is unnecessary when calling a shortcode using [Markdown notation].
+
+### Nesting
+
+The [`Parent`] method provides access to the parent shortcode context when the shortcode in question is called within the context of a parent shortcode. This provides an inheritance model.
+
+The following example is contrived but demonstrates the concept. Assume you have a `gallery` shortcode that expects one named `class` argument:
+
+```go-html-template {file="layouts/shortcodes/gallery.html"}
+<div class="{{ .Get "class" }}">
+ {{ .Inner }}
+</div>
+```
+
+You also have an `img` shortcode with a single named `src` argument that you want to call inside of `gallery` and other shortcodes, so that the parent defines the context of each `img`:
+
+```go-html-template {file="layouts/shortcodes/img.html"}
+{{ $src := .Get "src" }}
+{{ with .Parent }}
+ <img src="{{ $src }}" class="{{ .Get "class" }}-image">
+{{ else }}
+ <img src="{{ $src }}">
+{{ end }}
+```
+
+You can then call your shortcode in your content as follows:
+
+```text {file="content/example.md"}
+{{</* gallery class="content-gallery" */>}}
+ {{</* img src="/images/one.jpg" */>}}
+ {{</* img src="/images/two.jpg" */>}}
+{{</* /gallery */>}}
+{{</* img src="/images/three.jpg" */>}}
+```
+
+This will output the following HTML. Note how the first two `img` shortcodes inherit the `class` value of `content-gallery` set with the call to the parent `gallery`, whereas the third `img` only uses `src`:
+
+```html
+<div class="content-gallery">
+ <img src="/images/one.jpg" class="content-gallery-image">
+ <img src="/images/two.jpg" class="content-gallery-image">
+</div>
+<img src="/images/three.jpg">
+```
+
+### Other examples
+
+For guidance, consider examining Hugo's embedded shortcodes. The source code, available on [GitHub], can provide a useful model.
+
+## Detection
+
+The [`HasShortcode`] method allows you to check if a specific shortcode has been called on a page. For example, consider a custom audio shortcode:
+
+```text {file="content/example.md"}
+{{</* audio src=/audio/test.mp3 */>}}
+```
+
+You can use the `HasShortcode` method in your base template to conditionally load CSS if the audio shortcode was used on the page:
+
+```go-html-template {file="layouts/_default/baseof.html"}
+<head>
+ ...
+ {{ if .HasShortcode "audio" }}
+ <link rel="stylesheet" src="/css/audio.css">
+ {{ end }}
+ ...
+</head>
+```
+
+[`collections.IsSet`]: /functions/collections/isset/
+[`compare.Conditional`]: /functions/compare/conditional/
+[`Get`]: /methods/shortcode/get/
+[`HasShortcode`]: /methods/page/hasshortcode/
+[`Inner`]: /methods/shortcode/inner/
+[`IsNamedParams`]: /methods/shortcode/isnamedparams/
+[`Name`]: /methods/shortcode/name/
+[`Params`]: /methods/shortcode/params/
+[`Parent`]: /methods/shortcode/parent/
+[`Position`]: /methods/shortcode/position/
+[`RenderString`]: /methods/page/renderstring/
+[`with`]: /functions/go-template/with/
+[content management]: /content-management/shortcodes/
+[embedded shortcodes]: /shortcodes/
++[GitHub]: https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates/_shortcodes
+[introduction to templating]: /templates/introduction/
+[Markdown notation]: /content-management/shortcodes/#markdown-notation
+[named or positional]: /content-management/shortcodes/#arguments
+[shortcodes]: /content-management/shortcodes/
+[standard notation]: /content-management/shortcodes/#standard-notation
+[whitespace]: /templates/introduction/#whitespace
--- /dev/null
+---
+title: Data inspection
+linkTitle: Inspection
+description: Use template functions to inspect values and data structures.
+categories: []
+keywords: []
+---
+
+Use the [`debug.Dump`] function to inspect a data structure:
+
+```go-html-template
+<pre>{{ debug.Dump .Params }}</pre>
+```
+
+```text
+{
+ "date": "2023-11-10T15:10:42-08:00",
+ "draft": false,
+ "iscjklanguage": false,
+ "lastmod": "2023-11-10T15:10:42-08:00",
+ "publishdate": "2023-11-10T15:10:42-08:00",
+ "tags": [
+ "foo",
+ "bar"
+ ],
+ "title": "My first post"
+}
+```
+
+Use the [`printf`] function (render) or [`warnf`] function (log to console) to inspect simple data structures. The layout string below displays both value and data type.
+
+```go-html-template
+{{ $value := 42 }}
+{{ printf "%[1]v (%[1]T)" $value }} → 42 (int)
+```
+
++{{< new-in 0.146.0 />}}
++
++Use the [`templates.Current`] function to visually mark template execution boundaries or to display the template call stack.
++
+[`debug.Dump`]: /functions/debug/dump/
+[`printf`]: /functions/fmt/printf/
+[`warnf`]: /functions/fmt/warnf/
++[`templates.Current`]: /functions/templates/current/
--- /dev/null
- # Templates
- 'alias' = 'alias.html'
- 'disqus' = 'disqus.html'
- 'google_analytics' = 'google_analytics.html'
- 'opengraph' = 'opengraph.html'
- 'pagination' = 'pagination.html'
- 'robots' = '_default/robots.txt'
- 'rss' = '_default/rss.xml'
- 'schema' = 'schema.html'
- 'sitemap' = '_default/sitemap.xml'
- 'sitemapindex' = '_default/sitemapindex.xml'
- 'twitter_cards' = 'twitter_cards.html'
+# Used by the embedded template URL (eturl.html) shortcode.
+# Quoted all keys because some are not valid identifiers.
+
+# BaseURL
+'base_url' = 'https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates'
+
- 'render-codeblock-goat' = '_default/_markup/render-codeblock-goat.html'
- 'render-image' = '_default/_markup/render-image.html'
- 'render-link' = '_default/_markup/render-link.html'
- 'render-table' = '_default/_markup/render-table.html'
++# Partials
++'disqus' = '_partials/disqus.html'
++'google_analytics' = '_partials/google_analytics.html'
++'opengraph' = '_partials/opengraph.html'
++'pagination' = '_partials/pagination.html'
++'schema' = '_partials/schema.html'
++'twitter_cards' = '_partials/twitter_cards.html'
+
+# Render hooks
- 'details' = 'shortcodes/details.html'
- 'figure' = 'shortcodes/figure.html'
- 'gist' = 'shortcodes/gist.html'
- 'highlight' = 'shortcodes/highlight.html'
- 'instagram' = 'shortcodes/instagram.html'
- 'param' = 'shortcodes/param.html'
- 'qr' = 'shortcodes/qr.html'
- 'ref' = 'shortcodes/ref.html'
- 'relref' = 'shortcodes/relref.html'
- 'twitter' = 'shortcodes/twitter.html'
- 'twitter_simple' = 'shortcodes/twitter_simple.html'
- 'vimeo' = 'shortcodes/vimeo.html'
- 'vimeo_simple' = 'shortcodes/vimeo_simple.html'
- 'x' = 'shortcodes/x.html'
- 'x_simple' = 'shortcodes/x_simple.html'
- 'youtube' = 'shortcodes/youtube.html'
++'render-codeblock-goat' = '_markup/render-codeblock-goat.html'
++'render-image' = '_markup/render-image.html'
++'render-link' = '_markup/render-link.html'
++'render-table' = '_markup/render-table.html'
+
+# Shortcodes
++'details' = '_shortcodes/details.html'
++'figure' = '_shortcodes/figure.html'
++'gist' = '_shortcodes/gist.html'
++'highlight' = '_shortcodes/highlight.html'
++'instagram' = '_shortcodes/instagram.html'
++'param' = '_shortcodes/param.html'
++'qr' = '_shortcodes/qr.html'
++'ref' = '_shortcodes/ref.html'
++'relref' = '_shortcodes/relref.html'
++'vimeo' = '_shortcodes/vimeo.html'
++'vimeo_simple' = '_shortcodes/vimeo_simple.html'
++'x' = '_shortcodes/x.html'
++'x_simple' = '_shortcodes/x_simple.html'
++'youtube' = '_shortcodes/youtube.html'
++
++# Other
++'alias' = 'alias.html'
++'robots' = 'robots.txt'
++'rss' = 'rss.xml'
++'sitemap' = 'sitemap.xml'
++'sitemapindex' = 'sitemapindex.xml'
--- /dev/null
--- /dev/null
++{{- if eq .Type "alert" }}
++ {{- $alerts := dict
++ "caution" (dict "color" "red" "icon" "exclamation-triangle")
++ "important" (dict "color" "blue" "icon" "exclamation-circle")
++ "note" (dict "color" "blue" "icon" "information-circle")
++ "tip" (dict "color" "green" "icon" "light-bulb")
++ "warning" (dict "color" "orange" "icon" "exclamation-triangle")
++ }}
++
++ {{- $alertTypes := slice }}
++ {{- range $k, $_ := $alerts }}
++ {{- $alertTypes = $alertTypes | append $k }}
++ {{- end }}
++ {{- $alertTypes = $alertTypes | sort }}
++
++ {{- $alertType := strings.ToLower .AlertType }}
++ {{- if in $alertTypes $alertType }}
++ {{- partial "layouts/blocks/alert.html" (dict
++ "color" (or ((index $alerts $alertType).color) "blue")
++ "icon" (or ((index $alerts $alertType).icon) "information-circle")
++ "text" .Text
++ "title" .AlertTitle
++ "class" .Attributes.class
++ )
++ }}
++ {{- else }}
++ {{- errorf `Invalid blockquote alert type. Received %s. Expected one of %s (case-insensitive). See %s.` .AlertType (delimit $alertTypes ", " ", or ") .Page.String }}
++ {{- end }}
++{{- else }}
++ <blockquote {{- with .Attributes.class }}class="{{ . }}"{{- end }}>
++ {{ .Text }}
++ </blockquote>
++{{- end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */}}
++{{/*
++Renders a highlighted code block using the given options and attributes.
++
++In addition to the options available to the transform.Highlight function, you
++may also specify the following parameters:
++
++@param {bool} [copy=false] Whether to display a copy-to-clipboard button.
++@param {string} [file] The file name to display above the rendered code.
++@param {bool} [details=false] Whether to wrap the highlighted code block within a details element.
++@param {bool} [open=false] Whether to initially display the content of the details element.
++@param {string} [summary=Details] The content of the details summary element rendered from Markdown to HTML.
++
++@returns {template.HTML}
++
++@examples
++
++ ```go
++ fmt.Println("Hello world!")
++ ```
++
++ ```go {linenos=true file="layouts/index.html" copy=true}
++ fmt.Println("Hello world!")
++ ```
++*/}}
++{{/* prettier-ignore-end */}}
++
++{{- $copy := false }}
++{{- $file := or .Attributes.file "" }}
++{{- $details := false }}
++{{- $open := "" }}
++{{- $summary := or .Attributes.summary "Details" | .Page.RenderString }}
++{{- $ext := strings.TrimPrefix "." (path.Ext $file) }}
++{{- $lang := or .Type $ext "text" }}
++{{- if in (slice "html" "gotmpl") $lang }}
++ {{- $lang = "go-html-template" }}
++{{- end }}
++{{- if eq $lang "md" }}
++ {{- $lang = "text" }}
++{{- end }}
++
++{{- with .Attributes.copy }}
++ {{- if in (slice true "true" 1) . }}
++ {{- $copy = true }}
++ {{- else if in (slice false "false" 0) . }}
++ {{- $copy = false }}
++ {{- end }}
++{{- end }}
++
++{{- with .Attributes.details }}
++ {{- if in (slice true "true" 1) . }}
++ {{- $details = true }}
++ {{- else if in (slice false "false" 0) . }}
++ {{- $details = false }}
++ {{- end }}
++{{- end }}
++
++{{- with .Attributes.open }}
++ {{- if in (slice true "true" 1) . }}
++ {{- $open = "open" }}
++ {{- else if in (slice false "false" 0) . }}
++ {{- $open = "" }}
++ {{- end }}
++{{- end }}
++
++{{- if $details }}
++ <details class="cursor-pointer" {{ $open }}>
++ <summary>{{ $summary }}</summary>
++{{- end }}
++
++<div
++ x-data
++ class="render-hook-codeblock font-mono not-prose relative mt-6 mb-8 border-1 border-gray-200 dark:border-gray-800 bg-light dark:bg-dark">
++ {{- $fileSelectClass := "select-none" }}
++ {{- if $copy }}
++ {{- $fileSelectClass = "select-text" }}
++ <svg
++ class="absolute right-4 top-2 z-30 text-blue-600 hover:text-blue-500 dark:text-gray-400 dark:hover:text-gray-300 cursor-pointer w-6 h-6"
++ @click="$copy($refs.code)">
++ <use href="#icon--copy"></use>
++ </svg>
++ {{- end }}
++ {{- with $file }}
++ <div
++ class="san-serif text-sm inline-block leading-none pl-2 py-3 bg-gray-300 dark:bg-slate-700 w-full {{ $fileSelectClass }}
++">
++ {{ . }}
++ </div>
++ {{- end }}
++
++ <div x-ref="code">
++ {{- transform.Highlight (strings.TrimSpace .Inner) $lang .Options }}
++ </div>
++</div>
++
++{{- if $details }}
++ </details>
++{{- end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /* Last modified: 2025-01-19T14:44:56-08:00 */}}
++
++{{- /*
++Copyright 2025 Veriphor LLC
++
++Licensed under the Apache License, Version 2.0 (the "License"); you may not
++use this file except in compliance with the License. You may obtain a copy of
++the License at
++
++https://www.apache.org/licenses/LICENSE-2.0
++
++Unless required by applicable law or agreed to in writing, software
++distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
++WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
++License for the specific language governing permissions and limitations under
++the License.
++*/}}
++
++{{- /*
++This render hook resolves internal destinations by looking for a matching:
++
++ 1. Content page
++ 2. Page resource (a file in the current page bundle)
++ 3. Section resource (a file in the current section)
++ 4. Global resource (a file in the assets directory)
++
++It skips the section resource lookup if the current page is a leaf bundle.
++
++External destinations are not modified.
++
++You must place global resources in the assets directory. If you have placed
++your resources in the static directory, and you are unable or unwilling to move
++them, you must mount the static directory to the assets directory by including
++both of these entries in your site configuration:
++
++ [[module.mounts]]
++ source = 'assets'
++ target = 'assets'
++
++ [[module.mounts]]
++ source = 'static'
++ target = 'assets'
++
++By default, if this render hook is unable to resolve a destination, including a
++fragment if present, it passes the destination through without modification. To
++emit a warning or error, set the error level in your site configuration:
++
++ [params.render_hooks.link]
++ errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
++
++When you set the error level to warning, and you are in a development
++environment, you can visually highlight broken internal links:
++
++ [params.render_hooks.link]
++ errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
++ highlightBroken = true # true or false (default)
++
++This will add a "broken" class to anchor elements with invalid src attributes.
++Add a rule to your CSS targeting the broken links:
++
++ a.broken {
++ background: #ff0;
++ border: 2px solid #f00;
++ padding: 0.1em 0.2em;
++ }
++
++This render hook may be unable to resolve destinations created with the ref and
++relref shortcodes. Unless you set the error level to ignore you should not use
++either of these shortcodes in conjunction with this render hook.
++
++@context {string} Destination The link destination.
++@context {page} Page A reference to the page containing the link.
++@context {string} PlainText The link description as plain text.
++@context {string} Text The link description.
++@context {string} Title The link title.
++
++@returns {template.html}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- /* Initialize. */}}
++{{- $renderHookName := "link" }}
++
++{{- /* Verify minimum required version. */}}
++{{- $minHugoVersion := "0.141.0" }}
++{{- if lt hugo.Version $minHugoVersion }}
++ {{- errorf "The %q render hook requires Hugo v%s or later." $renderHookName $minHugoVersion }}
++{{- end }}
++
++{{- /* Error level when unable to resolve destination: ignore, warning, or error. */}}
++{{- $errorLevel := or site.Params.render_hooks.link.errorLevel "ignore" | lower }}
++
++{{- /* If true, adds "broken" class to broken links. Applicable in development environment when errorLevel is warning. */}}
++{{- $highlightBrokenLinks := or site.Params.render_hooks.link.highlightBroken false }}
++
++{{- /* Validate error level. */}}
++{{- if not (in (slice "ignore" "warning" "error") $errorLevel) }}
++ {{- errorf "The %q render hook is misconfigured. The errorLevel %q is invalid. Please check your site configuration." $renderHookName $errorLevel }}
++{{- end }}
++
++{{- /* Determine content path for warning and error messages. */}}
++{{- $contentPath := .Page.String }}
++
++{{- /* Parse destination. */}}
++{{- $u := urls.Parse .Destination }}
++
++{{- /* Set common message. */}}
++{{- $msg := printf "The %q render hook was unable to resolve the destination %q in %s" $renderHookName $u.String $contentPath }}
++
++{{- /* Set attributes for anchor element. */}}
++{{- $attrs := dict "href" $u.String }}
++{{- if eq $u.String "g" }}
++ {{- /* Destination is a glossary term. */}}
++ {{- $ctx := dict
++ "contentPath" $contentPath
++ "errorLevel" $errorLevel
++ "renderHookName" $renderHookName
++ "text" .Text
++ }}
++ {{- $attrs = partial "inline/h-rh-l/get-glossary-link-attributes.html" $ctx }}
++{{- else if $u.IsAbs }}
++ {{- /* Destination is a remote resource. */}}
++ {{- $attrs = merge $attrs (dict "rel" "external") }}
++{{- else }}
++ {{- with $u.Path }}
++ {{- with $p := or ($.PageInner.GetPage .) ($.PageInner.GetPage (strings.TrimRight "/" .)) }}
++ {{- /* Destination is a page. */}}
++ {{- $href := .RelPermalink }}
++ {{- with $u.RawQuery }}
++ {{- $href = printf "%s?%s" $href . }}
++ {{- end }}
++ {{- with $u.Fragment }}
++ {{- $ctx := dict
++ "contentPath" $contentPath
++ "errorLevel" $errorLevel
++ "page" $p
++ "parsedURL" $u
++ "renderHookName" $renderHookName
++ }}
++ {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
++ {{- $href = printf "%s#%s" $href . }}
++ {{- end }}
++ {{- $attrs = dict "href" $href }}
++ {{- else with $.PageInner.Resources.Get $u.Path }}
++ {{- /* Destination is a page resource; drop query and fragment. */}}
++ {{- $attrs = dict "href" .RelPermalink }}
++ {{- else with (and (ne $.Page.BundleType "leaf") ($.Page.CurrentSection.Resources.Get $u.Path)) }}
++ {{- /* Destination is a section resource, and current page is not a leaf bundle. */}}
++ {{- $attrs = dict "href" .RelPermalink }}
++ {{- else with resources.Get $u.Path }}
++ {{- /* Destination is a global resource; drop query and fragment. */}}
++ {{- $attrs = dict "href" .RelPermalink }}
++ {{- else }}
++ {{- if eq $errorLevel "warning" }}
++ {{- warnf $msg }}
++ {{- if and $highlightBrokenLinks hugo.IsDevelopment }}
++ {{- $attrs = merge $attrs (dict "class" "broken") }}
++ {{- end }}
++ {{- else if eq $errorLevel "error" }}
++ {{- errorf $msg }}
++ {{- end }}
++ {{- end }}
++ {{- else }}
++ {{- with $u.Fragment }}
++ {{- /* Destination is on the same page; prepend relative permalink. */}}
++ {{- $ctx := dict
++ "contentPath" $contentPath
++ "errorLevel" $errorLevel
++ "page" $.Page
++ "parsedURL" $u
++ "renderHookName" $renderHookName
++ }}
++ {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }}
++ {{- $attrs = dict "href" (printf "%s#%s" $.Page.RelPermalink .) }}
++ {{- else }}
++ {{- if eq $errorLevel "warning" }}
++ {{- warnf $msg }}
++ {{- if and $highlightBrokenLinks hugo.IsDevelopment }}
++ {{- $attrs = merge $attrs (dict "class" "broken") }}
++ {{- end }}
++ {{- else if eq $errorLevel "error" }}
++ {{- errorf $msg }}
++ {{- end }}
++ {{- end }}
++ {{- end }}
++{{- end }}
++
++{{- /* Render anchor element. */ -}}
++<a
++ {{- with .Title }}title="{{ . }}"{{- end }}
++ {{- range $k, $v := $attrs }}
++ {{- if $v }}
++ {{- printf " %s=%q" $k ($v | transform.HTMLEscape) | safeHTMLAttr }}
++ {{- end }}
++ {{- end -}}
++ >{{ .Text }}</a
++>
++
++{{- define "_partials/inline/h-rh-l/validate-fragment.html" }}
++ {{- /*
++ Validates the fragment portion of a link destination.
++
++ @context {string} contentPath The page containing the link.
++ @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error.
++ @context {page} page The page corresponding to the link destination
++ @context {struct} parsedURL The link destination parsed by urls.Parse.
++ @context {string} renderHookName The name of the render hook.
++ */}}
++
++ {{- /* Initialize. */}}
++ {{- $contentPath := .contentPath }}
++ {{- $errorLevel := .errorLevel }}
++ {{- $p := .page }}
++ {{- $u := .parsedURL }}
++ {{- $renderHookName := .renderHookName }}
++
++ {{- /* Validate. */}}
++ {{- with $u.Fragment }}
++ {{- if $p.Fragments.Identifiers.Contains . }}
++ {{- if gt ($p.Fragments.Identifiers.Count .) 1 }}
++ {{- $msg := printf "The %q render hook detected duplicate heading IDs %q in %s" $renderHookName . $contentPath }}
++ {{- if eq $errorLevel "warning" }}
++ {{- warnf $msg }}
++ {{- else if eq $errorLevel "error" }}
++ {{- errorf $msg }}
++ {{- end }}
++ {{- end }}
++ {{- else }}
++ {{- /* Determine target path for warning and error message. */}}
++ {{- $targetPath := "" }}
++ {{- with $p.File }}
++ {{- $targetPath = .Path }}
++ {{- else }}
++ {{- $targetPath = .Path }}
++ {{- end }}
++ {{- /* Set common message. */}}
++ {{- $msg := printf "The %q render hook was unable to find heading ID %q in %s. See %s" $renderHookName . $targetPath $contentPath }}
++ {{- if eq $targetPath $contentPath }}
++ {{- $msg = printf "The %q render hook was unable to find heading ID %q in %s" $renderHookName . $targetPath }}
++ {{- end }}
++ {{- /* Throw warning or error. */}}
++ {{- if eq $errorLevel "warning" }}
++ {{- warnf $msg }}
++ {{- else if eq $errorLevel "error" }}
++ {{- errorf $msg }}
++ {{- end }}
++ {{- end }}
++ {{- end }}
++{{- end }}
++
++{{- define "_partials/inline/h-rh-l/get-glossary-link-attributes.html" }}
++ {{- /*
++ Returns the anchor element attributes for a link to the given glossary term.
++
++ It first checks for the existence of a glossary page for the given term. If
++ no page is found, it then checks for a glossary page for the singular form of
++ the term. If neither page exists it throws a warning or error dependent on
++ the errorLevel setting
++
++ The returned href attribute does not point to the glossary term page.
++ Instead, via its fragment, it points to an entry on the glossary page.
++
++ @context {string} contentPath The page containing the link.
++ @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error.
++ @context {string} renderHookName The name of the render hook.
++ @context {string} text The link text.
++ */}}
++
++ {{- /* Get context.. */}}
++ {{- $contentPath := .contentPath }}
++ {{- $errorLevel := .errorLevel }}
++ {{- $renderHookName := .renderHookName }}
++ {{- $text := .text | transform.Plainify | strings.ToLower }}
++
++ {{- /* Initialize. */}}
++ {{- $glossaryPath := "/quick-reference/glossary" }}
++ {{- $termGiven := $text }}
++ {{- $termActual := "" }}
++ {{- $termSingular := inflect.Singularize $termGiven }}
++
++ {{- /* Verify that the glossary page exists. */}}
++ {{- $glossaryPage := site.GetPage $glossaryPath }}
++ {{- if not $glossaryPage }}
++ {{- errorf "The %q render hook was unable to find %s: see %s" $renderHookName $glossaryPath $contentPath }}
++ {{- end }}
++
++ {{- /* There's a better way to handle this, but it works for now. */}}
++ {{- $cheating := dict
++ "chaining" "chain"
++ "localize" "localization"
++ "localized" "localization"
++ "paginating" "paginate"
++ "walking" "walk"
++ "ci/cd" "cicd"
++ }}
++
++ {{- /* Verify that a glossary term page exists for the given term. */}}
++ {{- if site.GetPage (urls.JoinPath $glossaryPath ($termGiven | urlize)) }}
++ {{- $termActual = $termGiven }}
++ {{- else if site.GetPage (urls.JoinPath $glossaryPath ($termSingular | urlize)) }}
++ {{- $termActual = $termSingular }}
++ {{- else }}
++ {{- $termToTest := index $cheating $termGiven }}
++ {{- if site.GetPage (urls.JoinPath $glossaryPath ($termToTest | urlize)) }}
++ {{- $termActual = $termToTest }}
++ {{- end }}
++ {{- end }}
++
++ {{- if not $termActual }}
++ {{- errorf "The %q render hook was unable to find a glossary page for either the singular or plural form of the term %q: see %s" $renderHookName $termGiven $contentPath }}
++ {{- end }}
++
++ {{- /* Create the href attribute. */}}
++ {{- $href := "" }}
++ {{- if $termActual }}
++ {{- $href = fmt.Printf "%s#%s" $glossaryPage.RelPermalink (anchorize $termActual) }}
++ {{- end }}
++
++ {{- return (dict "href" $href) }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }}
++{{- with try (transform.ToMath .Inner $opts) }}
++ {{- with .Err }}
++ {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }}
++ {{- else }}
++ {{- .Value }}
++ {{- $.Page.Store.Set "hasMath" true }}
++ {{- end }}
++{{- end -}}
--- /dev/null
--- /dev/null
++<div class="overflow-x-auto">
++ <table
++ {{- range $k, $v := .Attributes }}
++ {{- if $v }}
++ {{- printf " %s=%q" $k $v | safeHTMLAttr }}
++ {{- end }}
++ {{- end }}>
++ <thead>
++ {{- range .THead }}
++ <tr>
++ {{- range . }}
++ <th {{- with .Alignment }} class="!text-{{ . }}"{{- end }}>
++ {{- .Text -}}
++ </th>
++ {{- end }}
++ </tr>
++ {{- end }}
++ </thead>
++ <tbody>
++ {{- range .TBody }}
++ <tr>
++ {{- range . }}
++ <td {{- with .Alignment }} class="!text-{{ . }}"{{- end }}>
++ {{- .Text -}}
++ </td>
++ {{- end }}
++ </tr>
++ {{- end }}
++ </tbody>
++ </table>
++</div>
--- /dev/null
--- /dev/null
++{{- with .Params.functions_and_methods.aliases }}
++ {{- $label := "Alias" }}
++ {{- if gt (len .) 1 }}
++ {{- $label = "Aliases" }}
++ {{- end }}
++ <p class="font-bold text-dark dark:text-light mt-2">{{ $label }}</p>
++ {{- range . }}
++ <div class="font-sm font-mono ml-3 sm:ml-6 mt-0 sm:mt-1">
++ {{- . -}}
++ </div>
++ {{- end }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- with .Params.functions_and_methods.returnType }}
++ <p class="font-bold text-dark dark:text-light mt-2">Returns</p>
++ <div class="font-sm font-mono ml-3 sm:ml-6 mt-0 sm:mt-1">
++ {{- . -}}
++ </div>
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- with .Params.functions_and_methods.signatures }}
++ <p class="font-bold text-dark dark:text-light">Syntax</p>
++ {{- range . }}
++ {{- $signature := . }}
++ {{- if $.Params.function.returnType }}
++ {{- $signature = printf "%s ⟼ %s" . $.Params.function.returnType }}
++ {{- end }}
++ <div class="font-sm font-mono ml-3 sm:ml-6 mt-0 sm:mt-1">
++ {{- $signature -}}
++ </div>
++ {{- end }}
++{{- end -}}
--- /dev/null
--- /dev/null
++<span class="h-3"></span>
++<table class="mt-auto">
++ <tbody>
++ <tr>
++ <td class="align-top text-red-700">weight:</td>
++ <td class="align-top pl-2 w-full">
++ {{ .Weight }}
++ </td>
++ </tr>
++ <tr>
++ <td class="align-top text-red-700">keywords:</td>
++ <td class="align-top pl-2">
++ {{ delimit (or .Keywords "") ", " }}
++ </td>
++ </tr>
++ <tr>
++ <td class="align-top text-red-700">categories:</td>
++ <td class="align-top pl-2">
++ {{ delimit (or .Params.categories "") ", " }}
++ </td>
++ </tr>
++ </tbody>
++</table>
--- /dev/null
--- /dev/null
++{{ $colors := slice "slate" "green" "cyan" "blue" }}
++{{ with .single }}
++ {{ $colors = slice . }}
++{{ end }}
++
++{{ $shades := slice 300 400 500 }}
++{{ if not .dark }}
++ {{ $shades = slice 700 800 }}
++{{ end }}
++{{ $hash := (hash.FNV32a .text) }}
++{{ $i := mod $hash (len $colors) }}
++{{ $j := mod $hash (len $shades) }}
++{{ $color := index $colors $i }}
++{{ $shade1 := index $shades $j }}
++{{ $shade2 := 0 }}
++{{ $shade3 := 0 }}
++{{ if gt $shade1 500 }}
++ {{ $shade2 = math.Min (sub $shade1 500) 100 | int }}
++ {{ $shade3 = sub $shade1 100 }}
++{{ else }}
++ {{ $shade2 = math.Max (add $shade1 500) 700 | int }}
++ {{ $shade3 = add $shade1 200 }}
++{{ end }}
++{{ $res := dict "color" $color "shade1" $shade1 "shade2" $shade2 "shade3" $shade3 }}
++{{ return $res }}
--- /dev/null
--- /dev/null
++{{ $url := "https://api.github.com/repos/gohugoio/hugo" }}
++{{ $cacheKey := print $url (now.Format "2006-01-02") }}
++{{ $headers := dict }}
++{{ with os.Getenv "HUGO_GH_TOKEN" }}
++ {{ $headers = dict "Authorization" (printf "Bearer %s" .) }}
++{{ end }}
++{{ $opts := dict "headers" $headers "key" $cacheKey }}
++{{ $githubRepoInfo := dict }}
++{{ with try (resources.GetRemote $url $opts) }}
++ {{ with .Err }}
++ {{ warnf "Failed to get GitHub repo info: %s" . }}
++ {{ else with (.Value | transform.Unmarshal) }}
++ {{ $githubRepoInfo = dict
++ "html_url" .html_url
++ "stargazers_url" .stargazers_url
++ "watchers_count" .watchers_count
++ "stargazers_count" .stargazers_count
++ "forks_count" .forks_count
++ "contributors_url" .contributors_url
++ "releases_url" .releases_url
++ "forks_count" .forks_count
++ }}
++ {{ else }}
++ {{ errorf "Unable to get remote resource %q" $url }}
++ {{ end }}
++{{ end }}
++
++{{ return $githubRepoInfo }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{/*
++Parses the serialized data from the given URL and returns a map or an array.
++
++Supports CSV, JSON, TOML, YAML, and XML.
++
++@param {string} . The URL from which to retrieve the serialized data.
++@returns {any}
++
++@example {{ partial "get-remote-data.html" "https://example.org/foo.json" }}
++*/}}
++{{/* prettier-ignore-end */ -}}
++{{ $url := . }}
++{{ $data := dict }}
++{{ with try (resources.GetRemote $url) }}
++ {{ with .Err }}
++ {{ errorf "%s" . }}
++ {{ else with .Value }}
++ {{ $data = .Content | transform.Unmarshal }}
++ {{ else }}
++ {{ errorf "Unable to get remote resource %q" $url }}
++ {{ end }}
++{{ end }}
++{{ return $data }}
--- /dev/null
--- /dev/null
++{{ with site.Config.Services.GoogleAnalytics.ID }}
++ <script
++ async
++ src="https://www.googletagmanager.com/gtag/js?id={{ . }}"></script>
++<script>
++ window.dataLayer = window.dataLayer || [];
++ function gtag(){dataLayer.push(arguments);}
++ gtag('js', new Date());
++
++ {{ $site := site.BaseURL | replaceRE "^https?://(www\\.)?([^/]+).*" "$2" }}
++ gtag('config', '{{ . }}', {'anonymize_ip': true, 'dimension1': '{{ $site }}', 'dimension2': '{{ getenv "BRANCH" }}'});
++
++/**
++* Function that tracks a click on an outbound link in Analytics.
++* Setting the transport method to 'beacon' lets the hit be sent
++* using 'navigator.sendBeacon' in browser that support it.
++*/
++var trackOutboundLink = function(id, url) {
++ gtag('event', 'click', {
++ 'event_category': 'outbound',
++ 'event_label': id,
++ 'transport_type': 'beacon'
++ });
++}
++
++</script>
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $r := .r }}
++{{ $attr := .attributes | default dict }}
++
++{{ if hugo.IsDevelopment }}
++ <link
++ rel="stylesheet"
++ href="{{ $r.RelPermalink }}"
++ {{ template `render-attributes` $attr }}>
++{{ else }}
++ {{ with $r | minify | fingerprint }}
++ <link
++ rel="stylesheet"
++ href="{{ .RelPermalink }}"
++ integrity="{{ .Data.Integrity }}"
++ crossorigin="anonymous"
++ {{ template `render-attributes` $attr }}>
++ {{ end }}
++{{ end }}
++
++{{ define "render-attributes" }}
++ {{- range $k, $v := . -}}
++ {{- if $v -}}
++ {{- printf ` %s=%q` $k $v | safeHTMLAttr -}}
++ {{- else -}}
++ {{- printf ` %s` $k | safeHTMLAttr -}}
++ {{- end -}}
++ {{- end -}}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $r := .r }}
++{{ $attr := .attributes | default dict }}
++{{ if hugo.IsDevelopment }}
++ <script
++ src="{{ $r.RelPermalink }}"
++ {{ template `render-attributes` $attr }}></script>
++{{ else }}
++ {{ with $r | fingerprint }}
++ <script
++ src="{{ .RelPermalink }}"
++ integrity="{{ .Data.Integrity }}"
++ crossorigin="anonymous"
++ {{ template `render-attributes` $attr }}></script>
++ {{ end }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $image := .image }}
++{{ $width := .width | default 1000 }}
++{{ $width1x := div $width 2 }}
++{{ $imageWebp := $image.Resize (printf "%dx webp" $width) }}
++{{ $image1x := $image.Resize (printf "%dx" $width1x) }}
++{{ $image1xWebp := $image.Resize (printf "%dx webp" $width1x) }}
++{{ $class := .class | default "h-64 tablet:h-96 lg:h-full w-full object-cover lg:absolute" }}
++{{ $loading := .loading | default "eager" }}
++<picture>
++ <source
++ srcset="{{ $imageWebp.RelPermalink }}"
++ type="image/webp"
++ media="(min-width: 1200px)">
++ <source
++ srcset="{{ $image.RelPermalink }}"
++ type="image/jpeg"
++ media="(min-width: 1200px)">
++ <source srcset="{{ $image1xWebp.RelPermalink }}" type="image/webp">
++ <source srcset="{{ $image1x.RelPermalink }}" type="image/jpeg">
++ <img
++ class="{{ $class }}"
++ src="{{ $image1x.RelPermalink }}"
++ alt=""
++ loading="{{ $loading }}"
++ width="{{ $image1x.Width }}"
++ height="{{ $image1x.Height }}">
++</picture>
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++We use the front matter keywords field to determine related content. To ensure
++consistency, during site build we validate each keyword against the entries in
++data/keywords.yaml.
++
++As of March 5, 2025, this feature is experimental, pending usability
++assessment. We anticipate that the number of additions to data/keywords.yaml
++will decrease over time, though the initial implementation will require some
++effort.
++*/}}
++{{/* prettier-ignore-end */ -}}
++{{- $t := debug.Timer "validateKeywords" }}
++{{- $allowedKeywords := collections.Apply site.Data.keywords "strings.ToLower" "." }}
++{{- range $p := site.Pages }}
++ {{- range .Params.keywords }}
++ {{- if not (in $allowedKeywords (lower .)) }}
++ {{- warnf "The word or phrase %q is not in the keywords data file. See %s." . $p.Page.String }}
++ {{- end }}
++ {{- end }}
++{{- end }}
++{{- $t.Stop }}
--- /dev/null
--- /dev/null
++{{- $title := .title | default "" }}
++{{- $color := .color | default "yellow" }}
++{{- $icon := .icon | default "exclamation-triangle" }}
++{{- $text := .text | default "" }}
++{{- $class := .class | default "mt-6 mb-8" }}
++<div
++ class="border-l-4 overflow-x-auto border-{{ $color }}-400 bg-{{ $color }}-50 dark:bg-{{ $color }}-950 border-1 border-{{ $color }}-100 dark:border-{{ $color }}-900 p-4 {{ $class }}">
++ <div class="flex">
++ <div class="shrink-0">
++ <svg class="fill-{{ $color }}-500 dark:fill-{{ $color }}-400 h-7 w-7">
++ <use href="#icon--{{ $icon }}"></use>
++ </svg>
++ </div>
++ <div class="ml-3">
++ {{- with $title }}
++ <h3 class="text-{{ $color }}-800">
++ {{ . }}
++ </h3>
++ {{- end }}
++ <div class="mt-2">
++ {{ $text }}
++ </div>
++ </div>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++<div x-data="{open: false}">
++ <div @click="open = true">
++ {{ .modal_button }}
++ </div>
++ <div
++ x-cloak
++ x-show="open"
++ x-transition:enter.opacity.duration.200ms
++ x-transition:leave.opacity.duration.300ms
++ x-trap.inert.noscroll="open"
++ @keydown.esc.window="open = false"
++ @click.self="open = false"
++ class="fixed inset-0 z-30 flex items-end justify-center bg-black/50 pb-8 backdrop-blur-xs sm:items-center"
++ role="dialog"
++ aria-modal="true"
++ aria-label="Modal">
++ <div
++ x-show="open"
++ x-transition:enter.opacity.scale.60.origin.top.right.duration.300ms.delay.200ms
++ class="flex content-center items-center justify-center max-w-lg flex-col overflow-hidden bg-white dark:bg-blue-950 border-2 border-gray-300 dark:border-gray-800 shadow-lg sm:shadow-xl">
++ <div
++ class="border-b border-outline border-gray-300 dark:border-gray-800 p-2 lg:p-4">
++ <h3 class="text-sm font-semibold">
++ {{ .modal_title }}
++ </h3>
++ </div>
++ {{ .modal_content }}
++ </div>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ $documentation := site.GetPage "/documentation" }}
++
++
++<nav aria-label="breadcrumb" class="flex breadcrumbs">
++ <ol class="inline-flex items-center flex-wrap tracking-tight">
++ {{ $currentSection := .CurrentSection }}
++ {{ $ancestors := .Ancestors.Reverse }}
++ {{ range $i, $p := $ancestors }}
++ {{ $isCurrentSection := eq $p $currentSection }}
++ {{/* We currently have a slightly odd structure. */}}
++ {{ if eq $p site.Home }}
++ {{ $p = $documentation }}
++ {{ end }}
++ <li class="flex items-center">
++ {{ $isLast := eq $i (sub (len $ancestors) 1) }}
++ <a
++ href="{{ $p.RelPermalink }}"
++ class="truncate text-blue-600 hover:text-blue-500 dark:text-blue-500 dark:hover:text-blue-400 {{ if $isCurrentSection }}
++ current-section
++ {{ end }}"
++ >{{ $p.LinkTitle }}</a
++ >
++ {{ if ne $ $documentation }}
++ {{ template "breadcrumbs-arrow" . }}
++ {{ end }}
++ </li>
++ {{ end }}
++ {{ if ne $ $documentation }}
++ {{ $isCurrentSection := eq $ $currentSection }}
++ <li
++ class="truncate text-gray-700 dark:text-gray-300 {{ if $isCurrentSection }}
++ current-section
++ {{ end }}">
++ {{ $.LinkTitle }}
++ </li>
++ {{ end }}
++ </ol>
++</nav>
++
++{{ define "breadcrumbs-arrow" }}
++ <svg class="fill-gray-500 dark:fill-gray-100 w-3 h-3 mx-2">
++ <use href="#icon--chevron-right"></use>
++ </svg>
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $humanDate := time.Format "January 2, 2006" . }}
++{{ $machineDate := time.Format "2006-01-02T15:04:05-07:00" . }}
++<time {{ printf "datetime=%q" $machineDate | safeHTMLAttr }}>
++ {{ $humanDate }}
++</time>
--- /dev/null
--- /dev/null
++<header>
++ {{ partial "layouts/breadcrumbs.html" . }}
++ {{ if and .IsPage (not (eq .Layout "list")) }}
++ <h1
++ class="font-display mt-6 sm:mt-8 text-3xl tracking-tight text-slate-900 dark:text-white">
++ {{ .Title }}
++ </h1>
++ {{ end }}
++</header>
--- /dev/null
--- /dev/null
++{{/* This is currently not in use, but kept in case I change my mind. */}}
++<nav
++ role="navigation"
++ id="explorer"
++ class="overflow-x-hidden w-54"
++ x-data="explorer"
++ data-turbo-permanent
++ @turbo:load.window="onLoad()"
++ @turbo:before-render.window="onBeforeRender()"
++ x-cloak>
++ <ul class="w-full">
++ {{ $root := site.GetPage "/" }}
++ {{ template "docs-explorer-section" (dict "p" $root "level" 0 ) }}
++ </ul>
++</nav>
++
++{{ define "docs-explorer-section" }}
++ {{ $p := .p }}
++ {{ $level := .level }}
++ {{ $pleft := $level }}
++ {{ if gt $level 0 }}
++ {{ $pleft = add $level 1 }}
++ {{ end }}
++ {{ $pl := printf "pl-%d" $pleft }}
++ {{ $pages := $p.Sections }}
++
++ {{ range $pages }}
++ {{ $hasChildren := gt (len .Pages) 0 }}
++ {{ $class := cond (eq $level 0) "text-primary hover:text-primary/70" "text-gray-900 dark:text-gray-400 hover:dark:text-gray-300" }}
++ <li class="w-full">
++ <a
++ @click="toggleNode('{{ .RelPermalink }}')"
++ href="{{ .RelPermalink }}"
++ x-ref="{{ .RelPermalink }}"
++ :class="isCurrent('{{ .RelPermalink }}') ? 'font-bold underline': 'font-normal'"
++ class="block cursor-pointer {{ $pl }} {{ $class }} focus:font-bold hover:underline focus:underline tracking-tight leading-7">
++ {{ .LinkTitle }}
++ </a>
++ {{ if $hasChildren }}
++ <ul class="w-full" x-show="isOpen('{{ .RelPermalink }}')">
++ {{ template "docs-explorer-section" (dict "p" . "level" (add $level 1)) }}
++ </ul>
++ {{ end }}
++ </li>
++ {{ end }}
++
++{{ end }}
--- /dev/null
--- /dev/null
++<footer
++ class="print:hidden bg-blue-950 mt-8 sm:mt-24 border-t-1 border-gray-800">
++ <div class="mx-auto max-w-7xl pt-16 pb-8 sm:pt-18 lg:pt-20">
++ <div class="xl:grid xl:grid-cols-3 xl:gap-8">
++ {{/* Column 1 */}}
++ <div class="flex flex-col items-center justify-between space-y-8">
++ <div class="text-gray-200">
++ By the
++ <a
++ href="https://github.com/gohugoio/hugo/graphs/contributors"
++ class="text-blue-300 hover:underline"
++ >Hugo Authors</a
++ ><br>
++ </div>
++
++ <img
++ src="/images/hugo-logo-wide.svg"
++ alt="Hugo Logo"
++ class="aspect-3/1 w-40">
++
++ <ul class="space-y-2 text-gray-200">
++ <li class="hover:text-white">
++ <a href="https://fosstodon.org/@gohugoio" class="">@GoHugoIO</a>
++ </li>
++ <li class="hover:text-white">
++ <a href="https://twitter.com/spf13" class="">@spf13</a>
++ </li>
++ <li class="hover:text-white">
++ <a href="https://twitter.com/bepsays" class="">@bepsays</a>
++ </li>
++ <li class="mt-6">
++ <a
++ href="https://github.com/gohugoio/hugo/issues/new"
++ class="text-sm/6 text-gray-200 hover:text-white"
++ >File an issue</a
++ >
++ </li>
++ <li>
++ <a
++ href="https://discourse.gohugo.io/"
++ class="text-sm/6 text-gray-200 hover:text-white"
++ >Get help</a
++ >
++ </li>
++ <li>
++ <a
++ href="https://themes.gohugo.io/"
++ class="text-sm/6 text-gray-200 hover:text-white"
++ >Find a theme</a
++ >
++ </li>
++ </ul>
++ </div>
++
++ {{/* Sponsors */}}
++ <div
++ class="mt-16 xl:mt-0 col-span-2 text-gray-200 max-w-3xl flex items-center content-center justify-center mx-auto">
++ {{ partial "layouts/home/sponsors.html" (dict
++ "ctx" .
++ "gtag" "footer"
++
++ )
++ }}
++ </div>
++ </div>
++ <div class="mt-16 border-t border-white/10 pt-8 sm:mt-20 lg:mt-24">
++ <p class="text-sm/6 text-gray-200">
++ The Hugo logos are copyright © Steve Francia 2013–{{ now.Year }}. The
++ Hugo Gopher is based on an original work by Renée French.
++ </p>
++ </div>
++ </div>
++</footer>
--- /dev/null
--- /dev/null
++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }}
++{{ $opts := dict "minify" true }}
++{{ with resources.Get "js/head-early.js" | js.Build $opts }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "async" "")) }}
++{{ end }}
++{{ with resources.Get "js/main.js" | js.Build $opts }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }}
++{{ end }}
++{{ with resources.Get "js/turbo.js" | js.Build $opts }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }}
++{{ end }}
--- /dev/null
--- /dev/null
++<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
++{{ hugo.Generator }}
++
++{{ if hugo.IsProduction }}
++ <meta name="robots" content="index, follow" />
++{{ else }}
++ <meta name="robots" content="noindex, nofollow" />
++{{ end }}
++
++<title>
++ {{ with .Title }}{{ . }} |{{ end }}
++ {{ .Site.Title }}
++</title>
++
++<link rel=apple-touch-icon sizes=180x180 href=/apple-touch-icon.png>
++<link rel=icon type=image/png href=/favicon-32x32.png sizes=32x32>
++<link rel=icon type=image/png href=/favicon-16x16.png sizes=16x16>
++<link rel=manifest href=/manifest.json>
++<link rel=mask-icon href=/safari-pinned-tab.svg color=#0594cb>
++
++<meta name="turbo-prefetch" content="true">
++<meta name="view-transition" content="same-origin">
++
++{{ range .AlternativeOutputFormats -}}
++ <link
++ rel="{{ .Rel }}"
++ type="{{ .MediaType.Type }}"
++ href="{{ .RelPermalink | safeURL }}" />
++{{ end -}}
++
++
++<meta
++ name="description"
++ content="{{ with .Description }}
++ {{ . }}
++ {{ else }}
++ {{ with .Site.Params.description }}{{ . }}{{ end }}
++ {{ end }}
++ " />
++
++
++
++{{ partial "opengraph/opengraph.html" . }}
++{{- template "_internal/schema.html" . -}}
++{{- template "_internal/twitter_cards.html" . -}}
++
++{{ if hugo.IsProduction }}
++ {{ partial "helpers/gtag.html" . }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ with partialCached "helpers/funcs/get-github-info.html" . "-" }}
++ <a
++ href="{{ .html_url | safeURL }}"
++ target="_blank"
++ class="font-normal font-mono tracking-tighter flex items-center bg-gray-100 hover:bg-gray-200 dark:bg-gray-600 dark:hover:bg-gray-700 text-sm text-black dark:text-white h-10 border-none cursor-pointer relative py-1 px-2 rounded-md"
++ aria-label="Star on GitHub">
++ <svg class="mr-[4px] fill-gray-800 dark:fill-gray-100 w-6 h-6">
++ <use href="#icon--github"></use>
++ </svg>
++ <span class="hidden md:inline mr-[3px]">Star</span>
++ <span class="hidden md:inline">{{ .stargazers_count }}</span>
++ <span class="inline md:hidden">
++ {{ printf "%0.1fk" (div .stargazers_count 1000) }}
++ </span>
++ </a>
++{{ end }}
--- /dev/null
--- /dev/null
++<header
++ x-data="navbar"
++ class="print:hidden sticky top-0 z-50 bg-blue-950 flex flex-none flex-wrap items-center justify-between px-4 py-5 shadow-md shadow-slate-900/5 transition duration-500 sm:px-6 lg:px-8 dark:shadow-none"
++ :class="$store.nav.scroll.atTop ? '': 'bg-blue-950/80'">
++ <div class="relative flex basis-0 items-center mr-2 lg:mr-8">
++ {{ with site.Home }}
++ <a
++ class="text-white text-xl font-bold upper"
++ href="{{ .RelPermalink }}"
++ aria-label="{{ .LinkTitle }}"
++ >HUGO</a
++ >
++ {{ end }}
++ </div>
++ <div
++ class=" relative flex flex-grow basis-0 items-center min-w-24 max-w-3xl overflow-x-auto">
++ {{ range .Site.Menus.global }}
++ <a
++ href="{{ .URL }}"
++ class="font-semibold text-gray-300 hover:text-gray-400 ml-4"
++ >{{ .Name }}</a
++ >
++ {{ end }}
++
++ </div>
++
++ <div class="-my-5 pl-2 grow-0">
++ {{/* Search. */}}
++ {{ partial "layouts/search/input.html" . }}
++ </div>
++ <div
++ class="relative ml-0 md:ml-8 flex basis-0 justify-end gap-0 sm:gap-1 xl:grow-1">
++ {{/* QR code. */}}
++ {{ partial "layouts/header/qr.html" . }}
++ {{/* Theme selector. */}}
++ {{ partial "layouts/header/theme.html" . }}
++
++ {{/* Social. */}}
++ <div
++ class="hidden sm:block ml-2 sm:ml-6 h-6 fill-slate-400 group-hover:fill-slate-500 dark:group-hover:fill-slate-300">
++ {{ partial "layouts/header/githubstars.html" . }}
++ </div>
++ </div>
++</header>
--- /dev/null
--- /dev/null
++{{ $t := debug.Timer "qr" }}
++{{ $qr := partial "_inline/qr" (dict
++ "page" $
++ "img_class" "w-10 bg-white view-transition-qr" )
++}}
++{{ $qrBig := partial "_inline/qr" (dict "page" $ "img_class" "w-64 p-4") }}
++{{ $t.Stop }}
++<div
++ class="hidden lg:block cursor-pointer outline-2 hover:outline-3 outline-blue-500 w-10 h-10">
++ {{ partial "layouts/blocks/modal.html" (dict "modal_button" $qr "modal_content" $qrBig "modal_title" (printf "QR code linking to %s" $.Permalink )) }}
++</div>
++
++{{ define "_partials/_inline/qr" }}
++ {{ $img_class := .img_class | default "w-10" }}
++ {{ with images.QR $.page.Permalink (dict "targetDir" "images/qr") }}
++
++ <img
++ src="{{ .RelPermalink }}"
++ width="{{ .Width }}"
++ height="{{ .Height }}"
++ @load="$event.target.classList.remove('_opacity-0')"
++ alt="QR code linking to {{ $.page.Permalink }}"
++ class="{{ $img_class }}">
++ {{ end }}
++{{ end }}
--- /dev/null
--- /dev/null
++<div class="ml-2 sm:ml-6 flex items-center" x-data>
++ <button
++ @click="$store.nav.userSettings.toggleColorScheme()"
++ aria-label="Toggle color scheme"
++ id="theme-toggle"
++ type="button"
++ class="inline-flex cursor-pointer items-center p-2 bg-orange-600 hover:bg-orange-700 dark:bg-gray-600 dark:hover:bg-gray-700 border border-transparent rounded-full shadow-sm text-white hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500">
++ <svg
++ aria-hidden="true"
++ class="w-3 h-3 sm:w-5 sm:h-5"
++ fill="none"
++ stroke="currentColor"
++ viewBox="0 0 24 24"
++ xmlns="http://www.w3.org/2000/svg">
++ <path
++ x-show="$store.nav.userSettings.colorScheme() == 1"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ stroke-width="2"
++ d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path>
++ <path
++ x-show="$store.nav.userSettings.colorScheme() == 2"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ stroke-width="2"
++ d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path>
++ <path
++ x-show="$store.nav.userSettings.colorScheme() == 3"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ stroke-width="2"
++ d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"></path>
++ </svg>
++ </button>
++</div>
--- /dev/null
--- /dev/null
++{{/* icons source: https://heroicons.com/ */}}
++{{ $dataTOML := `
++ [[features]]
++ heading = "Optimized for speed"
++ copy = "Written in Go, optimized for speed and designed for flexibility. With its advanced templating system and fast asset pipelines, Hugo renders a large site in seconds, often less."
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="M15.59 14.37a6 6 0 0 1-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 0 0 6.16-12.12A14.98 14.98 0 0 0 9.631 8.41m5.96 5.96a14.926 14.926 0 0 1-5.841 2.58m-.119-8.54a6 6 0 0 0-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 0 0-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 0 1-2.448-2.448 14.9 14.9 0 0 1 .06-.312m-2.24 2.39a4.493 4.493 0 0 0-1.757 4.306 4.493 4.493 0 0 0 4.306-1.758M16.5 9a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z" />
++ </svg>
++ """
++ [[features]]
++ heading = "Flexible framework"
++ copy = "With its multilingual support, and powerful taxonomy system, Hugo is widely used to create documentation sites, landing pages, corporate, government, nonprofit, education, news, event, and project sites."
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
++ </svg>
++ """
++ [[features]]
++ heading = "Fast assets pipeline"
++ copy = "Image processing (convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data), JavaScript bundling (tree shake, code splitting), Sass processing, great TailwindCSS support."
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
++ </svg>
++ """
++ [[features]]
++ heading = "Embedded web server"
++ copy = "Use Hugo's embedded web server during development to instantly see changes to content, structure, behavior, and presentation. "
++ icon = """<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
++ <path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418" />
++ </svg>
++ """
++ `
++}}
++{{ $data := $dataTOML | transform.Unmarshal }}
++<div class="mx-auto max-w-7xl px-6 lg:px-8">
++ <div class="mx-auto max-w-2xl lg:max-w-4xl">
++ <dl
++ class="grid max-w-xl grid-cols-1 gap-x-8 gap-y-10 lg:max-w-none lg:grid-cols-2 lg:gap-y-16">
++ {{ range $data.features }}
++ <div class="relative pl-16">
++ <dt
++ class="text-base/7 font-semibold text-gray-900 dark:text-gray-300">
++ <div
++ class="absolute top-0 left-0 flex size-10 items-center justify-center rounded-full bg-blue-600 p-2 fill-white text-white">
++ {{ .icon | safeHTML }}
++ </div>
++ {{ .heading }}
++ </dt>
++ <dd class="mt-2 text-base/7 text-gray-600 dark:text-gray-400">
++ {{ .copy }}
++ </dd>
++ </div>
++ {{ end }}
++
++ </dl>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }}
++<div class="mx-auto max-w-7xl px-6 lg:px-8">
++ <div
++ class="mx-auto grid max-w-2xl grid-cols-1 gap-x-8 gap-y-10 lg:mx-0 lg:max-w-none lg:grid-cols-2">
++ <div class="lg:pr-8">
++ <div class="lg:max-w-lg">
++ <p
++ class="text-4xl font-bold tracking-tight text-pretty text-gray-900 dark:text-gray-300 sm:text-5xl">
++ Open source
++ </p>
++ <p class="mt-6 text-lg/8 text-gray-600 dark:text-gray-400">
++ Hugo is open source and free to use. It is distributed under the
++ Apache 2.0 License.
++ </p>
++ <dl
++ class="mt-10 max-w-xl space-y-8 text-base/7 text-gray-600 dark:text-gray-300 lg:max-w-none">
++ <div class="relative pl-9">
++ <dt class="inline font-bold text-gray-900 dark:text-gray-300">
++ <svg
++ class="absolute top-1 left-1 size-5 text-blue-500"
++ xmlns="http://www.w3.org/2000/svg"
++ fill="none"
++ viewBox="0 0 24 24"
++ stroke-width="1.5"
++ stroke="currentColor"
++ class="size-6">
++ <path
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="M6 20.25h12m-7.5-3v3m3-3v3m-10.125-3h17.25c.621 0 1.125-.504 1.125-1.125V4.875c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125Z" />
++ </svg>
++ Popular.
++ </dt>
++ <dd class="inline ml-1">
++ Hugo has
++ {{ $githubInfo.stargazers_count | lang.FormatNumber 0 }}
++ stars on GitHub as of {{ now.Format "January 2, 2006" }}.
++ Join the crowd and hit the
++ <a
++ class="text-blue-500 hover:text-blue-500 font-semibold"
++ href="https://github.com/gohugoio/hugo"
++ >Star button</a
++ >.
++ </dd>
++ </div>
++ <div class="relative pl-9">
++ <dt class="inline font-bold text-gray-900 dark:text-gray-300">
++ <svg
++ class="absolute top-1 left-1 size-5 text-blue-500"
++ xmlns="http://www.w3.org/2000/svg"
++ fill="none"
++ viewBox="0 0 24 24"
++ stroke-width="1.5"
++ stroke="currentColor"
++ class="size-6">
++ <path
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="m20.893 13.393-1.135-1.135a2.252 2.252 0 0 1-.421-.585l-1.08-2.16a.414.414 0 0 0-.663-.107.827.827 0 0 1-.812.21l-1.273-.363a.89.89 0 0 0-.738 1.595l.587.39c.59.395.674 1.23.172 1.732l-.2.2c-.212.212-.33.498-.33.796v.41c0 .409-.11.809-.32 1.158l-1.315 2.191a2.11 2.11 0 0 1-1.81 1.025 1.055 1.055 0 0 1-1.055-1.055v-1.172c0-.92-.56-1.747-1.414-2.089l-.655-.261a2.25 2.25 0 0 1-1.383-2.46l.007-.042a2.25 2.25 0 0 1 .29-.787l.09-.15a2.25 2.25 0 0 1 2.37-1.048l1.178.236a1.125 1.125 0 0 0 1.302-.795l.208-.73a1.125 1.125 0 0 0-.578-1.315l-.665-.332-.091.091a2.25 2.25 0 0 1-1.591.659h-.18c-.249 0-.487.1-.662.274a.931.931 0 0 1-1.458-1.137l1.411-2.353a2.25 2.25 0 0 0 .286-.76m11.928 9.869A9 9 0 0 0 8.965 3.525m11.928 9.868A9 9 0 1 1 8.965 3.525" />
++ </svg>
++ Active.
++ </dt>
++ <dd class="inline ml-1">
++ Hugo has a large and active community. If you have questions or
++ need help, you can ask in the
++ <a
++ class="text-blue-500 hover:text-blue-500 font-semibold"
++ href="https://discourse.gohugo.io"
++ >Hugo forums</a
++ >.
++ </dd>
++ </div>
++ <div class="relative pl-9">
++ <dt class="inline font-bold text-gray-900 dark:text-gray-300">
++ <svg
++ class="absolute top-1 left-1 size-5 text-blue-500"
++ xmlns="http://www.w3.org/2000/svg"
++ fill="none"
++ viewBox="0 0 24 24"
++ stroke-width="1.5"
++ stroke="currentColor"
++ class="size-6">
++ <path
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h1.5C5.496 19.5 6 18.996 6 18.375m-3.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-1.5A1.125 1.125 0 0 1 18 18.375M20.625 4.5H3.375m17.25 0c.621 0 1.125.504 1.125 1.125M20.625 4.5h-1.5C18.504 4.5 18 5.004 18 5.625m3.75 0v1.5c0 .621-.504 1.125-1.125 1.125M3.375 4.5c-.621 0-1.125.504-1.125 1.125M3.375 4.5h1.5C5.496 4.5 6 5.004 6 5.625m-3.75 0v1.5c0 .621.504 1.125 1.125 1.125m0 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m1.5-3.75C5.496 8.25 6 7.746 6 7.125v-1.5M4.875 8.25C5.496 8.25 6 8.754 6 9.375v1.5m0-5.25v5.25m0-5.25C6 5.004 6.504 4.5 7.125 4.5h9.75c.621 0 1.125.504 1.125 1.125m1.125 2.625h1.5m-1.5 0A1.125 1.125 0 0 1 18 7.125v-1.5m1.125 2.625c-.621 0-1.125.504-1.125 1.125v1.5m2.625-2.625c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125M18 5.625v5.25M7.125 12h9.75m-9.75 0A1.125 1.125 0 0 1 6 10.875M7.125 12C6.504 12 6 12.504 6 13.125m0-2.25C6 11.496 5.496 12 4.875 12M18 10.875c0 .621-.504 1.125-1.125 1.125M18 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m-12 5.25v-5.25m0 5.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125m-12 0v-1.5c0-.621-.504-1.125-1.125-1.125M18 18.375v-5.25m0 5.25v-1.5c0-.621.504-1.125 1.125-1.125M18 13.125v1.5c0 .621.504 1.125 1.125 1.125M18 13.125c0-.621.504-1.125 1.125-1.125M6 13.125v1.5c0 .621-.504 1.125-1.125 1.125M6 13.125C6 12.504 5.496 12 4.875 12m-1.5 0h1.5m-1.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M19.125 12h1.5m0 0c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h1.5m14.25 0h1.5" />
++ </svg>
++ Frequent releases.
++ </dt>
++ <dd class="inline ml-1">
++ Hugo has a fast
++ <a
++ class="text-blue-500 hover:text-blue-500 font-semibold"
++ href="https://github.com/gohugoio/hugo/releases"
++ >release</a
++ >
++ cycle. The project is actively maintained and new features are
++ added regularly.
++ </dd>
++ </div>
++ </dl>
++ </div>
++ </div>
++ {{ partial "helpers/picture.html" (dict
++ "image" (resources.Get "images/hugo-github-screenshot.png")
++ "alt" "Hugo GitHub Repository"
++ "width" 640
++ "class" "w-full max-w-[38rem] ring-1 shadow-xl dark:shadow-gray-500 ring-gray-400/10")
++ }}
++ </div>
++</div>
--- /dev/null
--- /dev/null
++{{ $gtag := .gtag | default "unknown" }}
++{{ $gtag := .gtag | default "unknown" }}
++{{ $isFooter := (eq $gtag "footer") }}
++{{ $utmSource := cond $isFooter "hugofooter" "hugohome" }}
++{{ $containerClass := .containerClass | default "mx-auto max-w-7xl px-6 lg:px-8" }}
++{{ with .ctx.Site.Data.sponsors }}
++ <div class="{{ $containerClass }}">
++ <h2 class="font-bold text-2xl mb-6 tracking-tighter">Hugo Sponsors</h2>
++ <div class="grid grid-cols-1 lg:grid-cols-3 gap-x-8 gap-y-6">
++ {{ range .banners }}
++ <div class="max-w-64" style="background-color: {{ .bgcolor }};">
++ {{ $query_params := .query_params | default "" }}
++ {{ $url := .link }}
++ {{ if not .no_query_params }}
++ {{ $url = printf "%s?%s%s" .link $query_params (querify "utm_source" (.utm_source | default $utmSource ) "utm_medium" (.utm_medium | default "banner") "utm_campaign" (.utm_campaign | default "hugosponsor") "utm_content" (.utm_content | default "gohugoio")) | safeURL }}
++ {{ end }}
++ {{ $logo := resources.Get .logo }}
++ {{ $gtagID := printf "Sponsor %s %s" .name $gtag | title }}
++ <a
++ href="{{ $url }}"
++ title="{{ .title | default .name }}"
++ {{ if hugo.IsProduction }}
++ onclick="trackOutboundLink({{ printf "'%s', '%s'" $gtagID $url | safeJS }});"
++ {{ end }}
++ class="group inline-block w-full h-full shadow-md dark:shadow-gray-600"
++ {{ with .link_attr }}{{ . | safeHTMLAttr }}{{ end }}>
++ <div
++ class="flex w-full h-full p-8 items-center justify-center content-center transition duration-500 hover:scale-105 {{ if .show_on_hover }}
++ invisible group-hover:visible
++ {{ end }}">
++ {{ with $logo }}
++ {{ .Content | safeHTML }}
++ {{ else }}
++ <span class="text-4xl font-bold text-white">
++ {{ .name }}
++ </span>
++ {{ end }}
++ </div>
++ </a>
++ </div>
++ {{ end }}
++ </div>
++ </div>
++{{ end }}
--- /dev/null
--- /dev/null
++{{- if .IsHome }}
++ {{- partial "helpers/validation/validate-keywords.html" }}
++{{- end }}
--- /dev/null
--- /dev/null
++{{ if or .IsSection .IsPage }}
++ <div class="hidden print:flex justify-between border-b-1 border-b-gray-400 mb-4">
++ <p class="flex flex-col justify-end text-4xl mb-3">Hugo Documentation</p>
++ {{ with images.QR .Permalink (dict "scale" 3) }}
++ <img class="mb-2 -mr-2" src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="Link to {{ $.Permalink }}">
++ {{ end }}
++ </div>
++{{end }}
--- /dev/null
--- /dev/null
++{{ with resources.Get "js/body-start.js" | js.Build (dict "minify" true) }}
++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "" "")) }}
++{{ end }}
--- /dev/null
--- /dev/null
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--chevron-right" viewBox="0 0 20 20">
++ <path
++ fill-rule="evenodd"
++ d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
++ clip-rule="evenodd"></path>
++ </symbol>
++</svg>
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--search" viewBox="0 0 20 20">
++ <path
++ d="M16.293 17.707a1 1 0 0 0 1.414-1.414l-1.414 1.414ZM9 14a5 5 0 0 1-5-5H2a7 7 0 0 0 7 7v-2ZM4 9a5 5 0 0 1 5-5V2a7 7 0 0 0-7 7h2Zm5-5a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7v2Zm8.707 12.293-3.757-3.757-1.414 1.414 3.757 3.757 1.414-1.414ZM14 9a4.98 4.98 0 0 1-1.464 3.536l1.414 1.414A6.98 6.98 0 0 0 16 9h-2Zm-1.464 3.536A4.98 4.98 0 0 1 9 14v2a6.98 6.98 0 0 0 4.95-2.05l-1.414-1.414Z" />
++ </symbol>
++</svg>
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--anchor" viewBox="0 0 24 24">
++ <path d="M0 0h24v24H0z" fill="none" />
++ <path
++ d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z" />
++ </symbol>
++</svg>
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--copy" viewBox="0 0 24 24">
++ <path
++ fill="none"
++ stroke="currentColor"
++ stroke-width="1.5"
++ aria-hidden="true"
++ stroke-linecap="round"
++ stroke-linejoin="round"
++ d="M9 12h3.75M9 15h3.75M9 18h3.75m3 .75H18a2.25 2.25 0 002.25-2.25V6.108c0-1.135-.845-2.098-1.976-2.192a48.424 48.424 0 00-1.123-.08m-5.801 0c-.065.21-.1.433-.1.664 0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75 2.25 2.25 0 00-.1-.664m-5.8 0A2.251 2.251 0 0113.5 2.25H15c1.012 0 1.867.668 2.15 1.586m-5.8 0c-.376.023-.75.05-1.124.08C9.095 4.01 8.25 4.973 8.25 6.108V8.25m0 0H4.875c-.621 0-1.125.504-1.125 1.125v11.25c0 .621.504 1.125 1.125 1.125h9.75c.621 0 1.125-.504 1.125-1.125V9.375c0-.621-.504-1.125-1.125-1.125H8.25zM6.75 12h.008v.008H6.75V12zm0 3h.008v.008H6.75V15zm0 3h.008v.008H6.75V18z"></path>
++ </symbol>
++</svg>
++
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--github" viewBox="0 0 24 24" aria-hidden="true">
++ <path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C6.477 2 2 6.463 2 11.97c0 4.404 2.865 8.14 6.839 9.458.5.092.682-.216.682-.48 0-.236-.008-.864-.013-1.695-2.782.602-3.369-1.337-3.369-1.337-.454-1.151-1.11-1.458-1.11-1.458-.908-.618.069-.606.069-.606 1.003.07 1.531 1.027 1.531 1.027.892 1.524 2.341 1.084 2.91.828.092-.643.35-1.083.636-1.332-2.22-.251-4.555-1.107-4.555-4.927 0-1.088.39-1.979 1.029-2.675-.103-.252-.446-1.266.098-2.638 0 0 .84-.268 2.75 1.022A9.607 9.607 0 0 1 12 6.82c.85.004 1.705.114 2.504.336 1.909-1.29 2.747-1.022 2.747-1.022.546 1.372.202 2.386.1 2.638.64.696 1.028 1.587 1.028 2.675 0 3.83-2.339 4.673-4.566 4.92.359.307.678.915.678 1.846 0 1.332-.012 2.407-.012 2.734 0 .267.18.577.688.48 3.97-1.32 6.833-5.054 6.833-9.458C22 6.463 17.522 2 12 2Z"></path>
++ </symbol>
++</svg>
++
++{{/* https://heroicons.com/mini exclamation-circle */}}
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--exclamation-circle" viewBox="0 0 24 24" aria-hidden="true">
++ <path fill-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-8-5a.75.75 0 0 1 .75.75v4.5a.75.75 0 0 1-1.5 0v-4.5A.75.75 0 0 1 10 5Zm0 10a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" clip-rule="evenodd" />
++ </symbol>
++</svg>
++
++{{/* https://heroicons.com/mini exclamation-triangle */}}
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--exclamation-triangle" viewBox="0 0 24 24" aria-hidden="true">
++ <path fill-rule="evenodd" d="M8.485 2.495c.673-1.167 2.357-1.167 3.03 0l6.28 10.875c.673 1.167-.17 2.625-1.516 2.625H3.72c-1.347 0-2.189-1.458-1.515-2.625L8.485 2.495ZM10 5a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 10 5Zm0 9a1 1 0 1 0 0-2 1 1 0 0 0 0 2Z" clip-rule="evenodd" />
++ </symbol>
++</svg>
++
++{{/* https://heroicons.com/mini information-circle */}}
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--information-circle" viewBox="0 0 24 24" aria-hidden="true">
++ <path fill-rule="evenodd" d="M18 10a8 8 0 1 1-16 0 8 8 0 0 1 16 0Zm-7-4a1 1 0 1 1-2 0 1 1 0 0 1 2 0ZM9 9a.75.75 0 0 0 0 1.5h.253a.25.25 0 0 1 .244.304l-.459 2.066A1.75 1.75 0 0 0 10.747 15H11a.75.75 0 0 0 0-1.5h-.253a.25.25 0 0 1-.244-.304l.459-2.066A1.75 1.75 0 0 0 9.253 9H9Z" clip-rule="evenodd" />
++ </symbol>
++</svg>
++
++{{/* https://heroicons.com/mini light-bulb */}}
++<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
++ <symbol id="icon--light-bulb" viewBox="0 0 24 24" aria-hidden="true">
++ <path d="M10 1a6 6 0 0 0-3.815 10.631C7.237 12.5 8 13.443 8 14.456v.644a.75.75 0 0 0 .572.729 6.016 6.016 0 0 0 2.856 0A.75.75 0 0 0 12 15.1v-.644c0-1.013.762-1.957 1.815-2.825A6 6 0 0 0 10 1ZM8.863 17.414a.75.75 0 0 0-.226 1.483 9.066 9.066 0 0 0 2.726 0 .75.75 0 0 0-.226-1.483 7.553 7.553 0 0 1-2.274 0Z" />
++ </symbol>
++</svg>
--- /dev/null
--- /dev/null
++{{- with .CurrentSection.RegularPages }}
++ {{ $hasTocOrRelated := or ($.Store.Get "hasToc") ($.Store.Get "hasRelated") }}
++ <div
++ class="overflow-y-auto {{ if $hasTocOrRelated }}
++ max-h-96
++ {{ else }}
++ sticky top-[8rem] max-h-[70vh]
++ {{ end }} relative mt-2 mb-8"
++ data-turbo-preserve-scroll-container="in-this-section">
++ <h2
++ class="text-base font-semibold tracking-tight text-gray-600 dark:text-gray-400">
++ In this section
++ </h2>
++
++ <ul id="in-sthis-section" class="mt-2">
++ {{- range . }}
++ <li>
++ <a
++ class="text-sm {{ if eq . $ }}
++ font-bold text-blue-600 hover:text-blue-600
++ dark:hover:text-blue-200 dark:text-blue-200 focus:font-bold
++ scroll-active
++ {{ else }}
++ text-blue-600 hover:text-blue-500 dark:text-blue-500
++ dark:hover:text-blue-400
++ {{ end }}"
++ href="{{ .RelPermalink }}"
++ >{{ .LinkTitle }}</a
++ >
++ </li>
++ {{- end }}
++ </ul>
++ </div>
++{{- end }}
--- /dev/null
--- /dev/null
++<div class="print:hidden">
++ <hr class="border-t border-gray-200 dark:border-gray-800 my-10 lg:my-16">
++
++ <div class="text-gray-800 dark:text-gray-300 font-semibold">
++ Last updated:
++ {{ .Lastmod.Format "January 2, 2006" }}{{ with .GitInfo }}
++ :
++ <a
++ class="text-blue-600 hover:text-blue-500"
++ href="{{ $.Site.Params.ghrepo }}commit/{{ .Hash }}"
++ >{{ .Subject }} ({{ .AbbreviatedHash }})</a
++ >
++ {{ end }}
++ </div>
++
++ {{ with .File }}
++ {{ if not .IsContentAdapter }}
++ {{ $href := printf "%sedit/master/content/%s/%s" site.Params.ghrepo $.Lang .Path }}
++ <a
++ href="{{ $href }}"
++ class="mt-4 inline-block not-prose bg-blue-600 hover:bg-blue-800 text-white hover:text-white font-bold py-2 px-4 rounded">
++ Improve this page
++ </a>
++ {{ end }}
++ {{ end }}
++</div>
--- /dev/null
--- /dev/null
++{{- $heading := "See also" }}
++{{- $related := site.Pages.Related . }}
++{{- $related = $related | complement .CurrentSection.Pages | first 7 }}
++
++{{- with $related }}
++ {{ $.Store.Set "hasRelated" true }}
++ <h2
++ class="text-base font-semibold tracking-tight text-gray-600 dark:text-gray-400">
++ {{ $heading }}
++ </h2>
++ <ul class="mt-2 mb-8">
++ {{- range . }}
++ <li>
++ <a
++ class="text-sm text-blue-600 hover:text-blue-500 dark:text-blue-500 dark:hover:text-blue-400"
++ href="{{ .RelPermalink }}"
++ >{{ or .Params.altTitle .Title }}</a
++ >
++ </li>
++ {{- end }}
++ </ul>
++{{- end }}
--- /dev/null
--- /dev/null
++<div class="flex items-center gap-1">
++ <span class="">Search by</span
++ ><svg
++ width="77"
++ height="19"
++ aria-label="Algolia"
++ role="img"
++ id="l1"
++ class="fill-gray-600 dark:fill-gray-400"
++ xmlns="http://www.w3.org/2000/svg"
++ viewBox="0 0 2196.2 500">
++ <path
++ class=""
++ d="M1070.38,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"></path>
++ <rect
++ class="cls-1"
++ x="1845.88"
++ y="104.73"
++ width="62.58"
++ height="277.9"
++ rx="5.9"
++ ry="5.9"></rect>
++ <path
++ class=""
++ d="M1851.78,71.38h50.77c3.26,0,5.9-2.64,5.9-5.9V5.9c0-3.62-3.24-6.39-6.82-5.83l-50.77,7.95c-2.87,.45-4.99,2.92-4.99,5.83v51.62c0,3.26,2.64,5.9,5.9,5.9Z"></path>
++ <path
++ class=""
++ d="M1764.03,275.3V5.91c0-3.63-3.24-6.39-6.82-5.83l-50.46,7.94c-2.87,.45-4.99,2.93-4.99,5.84l.17,273.22c0,12.92,0,92.7,95.97,95.49,3.33,.1,6.09-2.58,6.09-5.91v-40.78c0-2.96-2.19-5.51-5.12-5.84-34.85-4.01-34.85-47.57-34.85-54.72Z"></path>
++ <path
++ class=""
++ d="M1631.95,142.72c-11.14-12.25-24.83-21.65-40.78-28.31-15.92-6.53-33.26-9.85-52.07-9.85-18.78,0-36.15,3.17-51.92,9.85-15.59,6.66-29.29,16.05-40.76,28.31-11.47,12.23-20.38,26.87-26.76,44.03-6.38,17.17-9.24,37.37-9.24,58.36,0,20.99,3.19,36.87,9.55,54.21,6.38,17.32,15.14,32.11,26.45,44.36,11.29,12.23,24.83,21.62,40.6,28.46,15.77,6.83,40.12,10.33,52.4,10.48,12.25,0,36.78-3.82,52.7-10.48,15.92-6.68,29.46-16.23,40.78-28.46,11.29-12.25,20.05-27.04,26.25-44.36,6.22-17.34,9.24-33.22,9.24-54.21,0-20.99-3.34-41.19-10.03-58.36-6.38-17.17-15.14-31.8-26.43-44.03Zm-44.43,163.75c-11.47,15.75-27.56,23.7-48.09,23.7-20.55,0-36.63-7.8-48.1-23.7-11.47-15.75-17.21-34.01-17.21-61.2,0-26.89,5.59-49.14,17.06-64.87,11.45-15.75,27.54-23.52,48.07-23.52,20.55,0,36.63,7.78,48.09,23.52,11.47,15.57,17.36,37.98,17.36,64.87,0,27.19-5.72,45.3-17.19,61.2Z"></path>
++ <path
++ class=""
++ d="M894.42,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"></path>
++ <path
++ class=""
++ d="M2133.97,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-14.52,22.58-22.99,49.63-22.99,78.73,0,44.89,20.13,84.92,51.59,111.1,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47,1.23,0,2.46-.03,3.68-.09,.36-.02,.71-.05,1.07-.07,.87-.05,1.75-.11,2.62-.2,.34-.03,.68-.08,1.02-.12,.91-.1,1.82-.21,2.73-.34,.21-.03,.42-.07,.63-.1,32.89-5.07,61.56-30.82,70.9-62.81v57.83c0,3.26,2.64,5.9,5.9,5.9h50.42c3.26,0,5.9-2.64,5.9-5.9V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,206.92c-12.2,10.16-27.97,13.98-44.84,15.12-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-42.24,0-77.12-35.89-77.12-79.37,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33v142.83Z"></path>
++ <path
++ class=""
++ d="M1314.05,104.73h-49.33c-48.36,0-90.91,25.48-115.75,64.1-11.79,18.34-19.6,39.64-22.11,62.59-.58,5.3-.88,10.68-.88,16.14s.31,11.15,.93,16.59c4.28,38.09,23.14,71.61,50.66,94.52,2.93,2.6,6.05,4.98,9.31,7.14,12.86,8.49,28.11,13.47,44.52,13.47h0c17.99,0,34.61-5.93,48.16-15.97,16.29-11.58,28.88-28.54,34.48-47.75v50.26h-.11v11.08c0,21.84-5.71,38.27-17.34,49.36-11.61,11.08-31.04,16.63-58.25,16.63-11.12,0-28.79-.59-46.6-2.41-2.83-.29-5.46,1.5-6.27,4.22l-12.78,43.11c-1.02,3.46,1.27,7.02,4.83,7.53,21.52,3.08,42.52,4.68,54.65,4.68,48.91,0,85.16-10.75,108.89-32.21,21.48-19.41,33.15-48.89,35.2-88.52V110.63c0-3.26-2.64-5.9-5.9-5.9h-56.32Zm0,64.1s.65,139.13,0,143.36c-12.08,9.77-27.11,13.59-43.49,14.7-.16,.01-.33,.03-.49,.04-1.12,.07-2.24,.1-3.36,.1-1.32,0-2.63-.03-3.94-.1-40.41-2.11-74.52-37.26-74.52-79.38,0-10.25,1.96-20.01,5.42-28.98,11.22-29.12,38.77-49.74,71.06-49.74h49.33Z"></path>
++ <path
++ class="cls-1"
++ d="M249.83,0C113.3,0,2,110.09,.03,246.16c-2,138.19,110.12,252.7,248.33,253.5,42.68,.25,83.79-10.19,120.3-30.03,3.56-1.93,4.11-6.83,1.08-9.51l-23.38-20.72c-4.75-4.21-11.51-5.4-17.36-2.92-25.48,10.84-53.17,16.38-81.71,16.03-111.68-1.37-201.91-94.29-200.13-205.96,1.76-110.26,92-199.41,202.67-199.41h202.69V407.41l-115-102.18c-3.72-3.31-9.42-2.66-12.42,1.31-18.46,24.44-48.53,39.64-81.93,37.34-46.33-3.2-83.87-40.5-87.34-86.81-4.15-55.24,39.63-101.52,94-101.52,49.18,0,89.68,37.85,93.91,85.95,.38,4.28,2.31,8.27,5.52,11.12l29.95,26.55c3.4,3.01,8.79,1.17,9.63-3.3,2.16-11.55,2.92-23.58,2.07-35.92-4.82-70.34-61.8-126.93-132.17-131.26-80.68-4.97-148.13,58.14-150.27,137.25-2.09,77.1,61.08,143.56,138.19,145.26,32.19,.71,62.03-9.41,86.14-26.95l150.26,133.2c6.44,5.71,16.61,1.14,16.61-7.47V9.48C499.66,4.25,495.42,0,490.18,0H249.83Z"></path>
++ </svg>
++</div>
--- /dev/null
--- /dev/null
++{{ $textColor := "text-gray-300" }}
++{{ $fillColor := "fill-slate-400 dark:fill-slate-500" }}
++{{ if .standalone }}
++ {{ $textColor = "text-gray-800 dark:text-gray-300 " }}
++ {{ $fillColor = "fill-slate-500 dark:fill-slate-400" }}
++{{ end }}
++
++
++<button
++ {{ if .standalone }}
++ x-data @click="$dispatch('search-toggle')"
++ {{ end }}
++ type="button"
++ aria-label="Search"
++ class="{{ $textColor }} grid cursor-pointer w-full lg:w-56 grid-cols-[auto_1fr_auto] items-center rounded-md px-2 sm:px-4 py-2 text-left text-xs/6 lg:text-sm/6 outline-0 sm:outline-1 -outline-offset-1 outline-gray-600">
++ <svg
++ class="{{ $fillColor }} pointer-events-none -ml-0.5 mr-2 size-5 sm:size-4">
++ <use href="#icon--search"></use>
++ </svg>
++ <span class="hidden lg:inline">Search docs</span>
++ <span class="hidden lg:inline">/</span>
++</button>
--- /dev/null
--- /dev/null
++<div x-data="search" class="flex w-full">
++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" false) }}
++ {{ partial "layouts/search/results.html" . }}
++</div>
--- /dev/null
--- /dev/null
++<div
++ class="fixed inset-0 overflow-hidden z-20"
++ :class="{'fixed': open}"
++ aria-label="Search docs"
++ role="dialog"
++ aria-modal="true"
++ @keydown.right="$focus.next()"
++ @keydown.left="$focus.previous()"
++ @keydown.esc="open=false"
++ x-cloak>
++ <div class="absolute inset-0 overflow-hidden z-20" x-show="open">
++ <div class="absolute inset-0" aria-hidden="true"></div>
++
++ <div
++ class="pointer-events-none fixed inset-y-0 right-0 flex max-w-full pl-10"
++ @click.outside="open = false">
++ <div
++ class="pointer-events-auto w-screen max-w-md"
++ x-show="open"
++ x-transition:enter="transform transition ease-in-out duration-300 sm:duration-500"
++ x-transition:enter-start="translate-x-full"
++ x-transition:enter-end="translate-x-0"
++ x-transition:leave="transform transition ease-in-out duration-300 sm:duration-500"
++ x-transition:leave-start="translate-x-0"
++ x-transition:leave-end="translate-x-full">
++ <div
++ class="flex h-full flex-col overflow-y-scroll dark:bg-blue-950/96 bg-white py-6 shadow-sm dark:shadow-gray-800">
++ <div class="px-4 sm:px-6">
++ <div class="flex items-start justify-between">
++ <input
++ x-model.debounce.100ms="query"
++ @click="search()"
++ type="search"
++ arial-label="Search"
++ class="text-gray-800 dark:text-gray-100 bg-white/40 dark:bg-gray-900 shadow rounded border-0 p-3 w-full"
++ placeholder="Search docs"
++ x-ref="input">
++ </div>
++ </div>
++ <div class="relative mt-6 flex-1 px-4 sm:px-6 h-full">
++ <ul
++ role="list"
++ class="divide-y divide-gray-200 dark:divide-gray-900 h-[calc(100%-6rem)] overflow-y-auto">
++ <template
++ x-for="[group, entries] in Object.entries(result)"
++ :key="group">
++ <li class="py-4">
++ <div
++ class="mb-1 dark:text-gray-300 font-semibold uppercase tracking-widest text-sm"
++ x-text="group"></div>
++ <template x-for="entry in entries" :key="entry.objectID">
++ <a
++ class="flex flex-nowrap space-x-4 py-2 text-sm leading-5 text-gray-900 dark:text-gray-500 hover:dark:text-gray-800 hover:bg-gray-50 dark:hover:bg-gray-500 focus:outline-none focus:bg-gray-50 dark:focus:bg-gray-800 cursor-pointer transition duration-150 ease-in-out"
++ :href="entry.url">
++ <span
++ class="w-1/3 text-xs text-right text-gray-500 dark:text-gray-300"
++ x-text="entry.hierarchy.lvl1">
++ </span>
++ <div class="w-2/3">
++ <h3
++ class="text-md font-bold"
++ x-html="entry.getHeadingHTML()"></h3>
++ <template
++ x-if="entry._snippetResult && entry._snippetResult.content">
++ <div class="two-lines-ellipsis mt-1">
++ <span>…</span>
++ <span x-html="entry._snippetResult.content.value">
++ </span>
++ <span>…</span>
++ </div>
++ </template>
++ </div>
++ </a>
++ </template>
++ </li>
++ </template>
++ </ul>
++ </div>
++ {{/* End listing */ -}}
++ </div>
++ </div>
++ <div
++ class="z-40 fixed pointer-events-auto bottom-0 right-0 dark:text-gray-300 text-gray-800 float-right mr-8 mb-4 text-sm lg:text-md"
++ x-show="open"
++ x-transition.opacity.duration.800ms>
++ {{ partial "layouts/search/algolialogo.html" }}
++ </div>
++ </div>
++ </div>
++</div>
--- /dev/null
--- /dev/null
++<template id="anchor-heading">
++ <a class="hidden group-hover:inline-flex items-center" aria-label="Anchor">
++ <svg class="ml-2 fill-primary hover:fill-primary/70 w-4 h-4">
++ <use href="#icon--anchor"></use>
++ </svg>
++ </a>
++</template>
--- /dev/null
--- /dev/null
++{{ with .Fragments }}
++ {{ with .Headings }}
++ <div
++ x-data="toc"
++ class="sticky top-[8rem] h-screen overflow-y-auto overflow-x-hidden">
++ <h2
++ class="text-base font-semibold tracking-tight text-gray-600 dark:text-gray-400">
++ On this page
++ </h2>
++ <nav class="w-56 mt-2">
++ <ul>
++ {{ template "render-toc-level" (dict "h" . "p" $) }}
++ </ul>
++ </nav>
++ </div>
++ {{ end }}
++{{ end }}
++
++{{ define "render-toc-level" }}
++ {{ range .h }}
++ {{ if and .ID (and (ge .Level 2) (le .Level 4)) }}
++ {{ $indentation := "ml-0" }}
++ {{ if eq .Level 3 }}
++ {{ $indentation = "ml-2 lg:ml-3" }}
++ {{ else if eq .Level 4 }}
++ {{ $indentation = "ml-4 lg:ml-6" }}
++ {{ end }}
++ {{ $.p.Store.Set "hasToc" true }}
++ <li>
++ <a
++ href="#{{ .ID }}"
++ x-ref="{{ .ID }}"
++ @click.stop="setActive('{{ .ID }}')"
++ class="block pb-1 text-blue-600 hover:text-blue-500 dark:text-blue-500 dark:hover:text-blue-400 text-sm {{ $indentation }}"
++ :class="{'font-bold dark:text-blue-200 dark:hover:text-blue-300' : activeHeading === '{{ .ID }}'}">
++ {{ .Title | safeHTML }}
++ </a>
++ </li>
++ {{ end }}
++ {{ with .Headings }}
++ <ul>
++ {{ template "render-toc-level" (dict "h" . "p" $.p) }}
++ </ul>
++ {{ end }}
++ {{ end }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{ $images := $.Resources.ByType "image" }}
++{{ $featured := $images.GetMatch "*feature*" }}
++{{ if not $featured }}
++ {{ $featured = $images.GetMatch "{*cover*,*thumbnail*}" }}
++{{ end }}
++{{ if not $featured }}
++ {{ $featured = resources.Get "/opengraph/gohugoio-card-base-1.png" }}
++ {{ $size := 80 }}
++ {{ $title := $.LinkTitle }}
++ {{ if gt (len $title) 20 }}
++ {{ $size = 70 }}
++ {{ end }}
++
++ {{ $text := $title }}
++ {{ $textOptions := dict
++ "color" "#FFF"
++ "size" $size
++ "lineSpacing" 10
++ "x" 65 "y" 80
++ "font" (resources.Get "/opengraph/mulish-black.ttf")
++ }}
++
++ {{ $featured = $featured | images.Filter (images.Text $text $textOptions) }}
++{{ end }}
++
++{{ return $featured }}
--- /dev/null
--- /dev/null
++<meta property="og:title" content="{{ .Title }}">
++<meta
++ property="og:description"
++ content="{{ with .Description }}
++ {{ . }}
++ {{ else }}
++ {{ if .IsPage }}
++ {{ .Summary }}
++ {{ else }}
++ {{ with .Site.Params.description }}{{ . }}{{ end }}
++ {{ end }}
++ {{ end }}">
++<meta
++ property="og:type"
++ content="{{ if .IsPage }}
++ article
++ {{ else }}
++ website
++ {{ end }}">
++<meta property="og:url" content="{{ .Permalink }}">
++
++{{- with $.Params.images -}}
++ {{- range first 6 . }}
++ <meta property="og:image" content="{{ . | absURL }}">
++ {{ end -}}
++{{- else -}}
++ {{- $featured := partial "opengraph/get-featured-image.html" . }}
++ {{- with $featured -}}
++ <meta property="og:image" content="{{ $featured.Permalink }}">
++ {{- else -}}
++ {{- with $.Site.Params.images }}
++ <meta property="og:image" content="{{ index . 0 | absURL }}">
++ {{ end -}}
++ {{- end -}}
++{{- end -}}
++
++{{- if .IsPage }}
++ {{- $iso8601 := "2006-01-02T15:04:05-07:00" -}}
++ <meta property="article:section" content="{{ .Section }}">
++ {{ with .PublishDate }}
++ <meta
++ property="article:published_time"
++ {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>
++ {{ end }}
++ {{ with .Lastmod }}
++ <meta
++ property="article:modified_time"
++ {{ .Format $iso8601 | printf "content=%q" | safeHTMLAttr }}>
++ {{ end }}
++{{- end -}}
++
++{{- with .Params.audio }}<meta property="og:audio" content="{{ . }}">{{ end }}
++{{- with .Params.locale }}
++ <meta property="og:locale" content="{{ . }}">
++{{ end }}
++{{- with .Site.Params.title }}
++ <meta property="og:site_name" content="{{ . }}">
++{{ end }}
++{{- with .Params.videos }}
++ {{- range . }}
++ <meta property="og:video" content="{{ . | absURL }}">
++ {{ end }}
++
++{{ end }}
++
++{{- /* If it is part of a series, link to related articles */}}
++{{- $permalink := .Permalink }}
++{{- $siteSeries := .Site.Taxonomies.series }}
++{{ with .Params.series }}
++ {{- range $name := . }}
++ {{- $series := index $siteSeries ($name | urlize) }}
++ {{- range $page := first 6 $series.Pages }}
++ {{- if ne $page.Permalink $permalink }}
++ <meta property="og:see_also" content="{{ $page.Permalink }}">
++ {{ end }}
++ {{- end }}
++ {{ end }}
++
++{{ end }}
++
++{{- /* Facebook Page Admin ID for Domain Insights */}}
++{{- with site.Params.social.facebook_admin }}
++ <meta property="fb:admins" content="{{ . }}">
++{{ end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders an HTML template of Chroma lexers and their aliases.
++
++@example {{< chroma-lexers >}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++<div class="overflow-x-auto">
++ <table>
++ <thead>
++ <th>Language</th>
++ <th>Identifiers</th>
++ </thead>
++ <tbody>
++ {{- range site.Data.docs.chroma.lexers }}
++ <tr>
++ <td>{{ .Name }}</td>
++ <td>
++ {{- range $k, $_ := .Aliases }}
++ {{- if $k }},{{ end }}
++ <code>{{ . }}</code>
++ {{- end }}
++ </td>
++ </tr>
++ {{- end }}
++ </tbody>
++ </table>
++</div>
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders syntax-highlighted configuration data in JSON, TOML, and YAML formats.
++
++@param {string} [config] The section of site.Data.docs.config to render.
++@param {bool} [copy=false] Whether to display a copy-to-clipboard button.
++@param {string} [dataKey] The section of site.Data.docs to render.
++@param {string} [file] The file name to display above the rendered code.
++@param {bool} [fm=false] Whether to render the code as front matter.
++@param {bool} [skipHeader=false] Whether to omit top level key(s) when rendering a section of site.Data.docs.config.
++
++@example {{< code-toggle file=hugo config=build />}}
++
++@example {{< code-toggle file=content/example.md fm="true" }}
++ title='Example'
++ draft='false
++ {{< /code-toggle }}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- /* Initialize. */}}
++{{- $config := "" }}
++{{- $copy := false }}
++{{- $dataKey := "" }}
++{{- $file := "" }}
++{{- $fm := false }}
++{{- $skipHeader := false }}
++
++{{- /* Get parameters. */}}
++{{- $config = .Get "config" }}
++{{- $dataKey = .Get "dataKey" }}
++{{- $file = .Get "file" }}
++{{- if in (slice "false" false 0) (.Get "copy") }}
++ {{- $copy = false }}
++{{- else if in (slice "true" true 1) (.Get "copy") }}
++ {{- $copy = true }}
++{{- end }}
++{{- if in (slice "false" false 0) (.Get "fm") }}
++ {{- $fm = false }}
++{{- else if in (slice "true" true 1) (.Get "fm") }}
++ {{- $fm = true }}
++{{- end }}
++{{- if in (slice "false" false 0) (.Get "skipHeader") }}
++ {{- $skipHeader = false }}
++{{- else if in (slice "true" true 1) (.Get "skipHeader") }}
++ {{- $skipHeader = true }}
++{{- end }}
++
++{{- /* Define constants. */}}
++{{- $delimiters := dict "toml" "+++" "yaml" "---" }}
++{{- $langs := slice "yaml" "toml" "json" }}
++{{- $placeHolder := "#-hugo-placeholder-#" }}
++
++{{- /* Render. */}}
++{{- $code := "" }}
++{{- if $config }}
++ {{- $file = $file | default "hugo" }}
++ {{- $sections := (split $config ".") }}
++ {{- $configSection := index $.Site.Data.docs.config $sections }}
++ {{- $code = dict $sections $configSection }}
++ {{- if $skipHeader }}
++ {{- $code = $configSection }}
++ {{- end }}
++{{- else if $dataKey }}
++ {{- $file = $file | default $dataKey }}
++ {{- $sections := (split $dataKey ".") }}
++ {{- $code = index $.Site.Data.docs $sections }}
++{{- else }}
++ {{- $code = $.Inner }}
++{{- end }}
++
++
++<div x-data class="shortcode-code not-prose relative p-0 mt-6 mb-8">
++ {{- if $copy }}
++ <svg
++ class="absolute right-4 top-12 z-30 text-blue-600 hover:text-blue-500 cursor-pointer w-6 h-6"
++ @click="$copy($refs[$store.nav.userSettings.settings.configFileType])">
++ <use href="#icon--copy"></use>
++ </svg>
++ {{- end }}
++ <nav class="relative flex" aria-label="Tabs">
++ {{- with $file }}
++ <div
++ class="select-none flex-none text-sm px-2 content-center border-b-1 border-gray-300 dark:border-gray-700"
++ aria-label="Filename">
++ {{ . }}{{ if not $fm }}.{{ end }}
++ </div>
++ {{- end }}
++ {{- range $i, $lang := $langs }}
++ {{- $isLast := eq (add $i 1) (len $langs) }}
++ <button
++ x-on:click="$store.nav.userSettings.settings.configFileType = '{{ index $langs $i }}'"
++ aria-label="{{ printf `Toggle %s` . }}"
++ class="px-3 py-2 font-semibold text-black dark:text-slate-200 border-l-1 border-t-1 {{ if $isLast }}
++ border-r-1
++ {{ end }} border-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 dark:border-gray-700 cursor-pointer relative min-w-0 flex-1 overflow-hidden text-sm no-underline text-center focus:z-10 overflow-x-auto"
++ :class="$store.nav.userSettings.settings.configFileType === '{{ index $langs $i }}' ? 'border-b-0 bg-light dark:bg-dark' : 'border-b-1'">
++ <span class="select-none">
++ {{ . }}
++ </span>
++ </button>
++ {{- end }}
++ </nav>
++ {{- if $code }}
++ {{- range $i, $lang := $langs }}
++ <div
++ class="max-h-96 overflow-y-auto border-l-1 border-b-1 border-r-1 border-gray-300 dark:border-gray-700"
++ x-ref="{{ $lang }}"
++ x-cloak
++ x-transition:enter.opacity.duration.300ms
++ x-show="$store.nav.userSettings.settings.configFileType === '{{ index $langs $i }}'">
++ {{- $hCode := $code | transform.Remarshal . }}
++ {{- if and $fm (in (slice "toml" "yaml") .) }}
++ {{- $hCode = printf "%s\n%s\n%s" $placeHolder $hCode $placeHolder }}
++ {{- end }}
++ {{- $hCode = $hCode | replaceRE `\n+` "\n" }}
++ {{- highlight $hCode . "" | replaceRE $placeHolder (index $delimiters .) | safeHTML }}
++ </div>
++ {{- end }}
++ {{- end }}
++</div>
--- /dev/null
--- /dev/null
++{{ $package := (index .Params 0) }}
++{{ $listname := (index .Params 1) }}
++{{ $filter := split (index .Params 2) " " }}
++{{ $filter1 := index $filter 0 }}
++{{ $filter2 := index $filter 1 }}
++{{ $filter3 := index $filter 2 }}
++
++{{ $list := (index (index .Site.Data.docs $package) $listname) }}
++{{ $fields := after 3 .Params }}
++{{ $list := where $list $filter1 $filter2 $filter3 }}
++
++
++<div class="overflow-x-auto">
++ <table>
++ <thead>
++ <tr>
++ {{ range $fields }}
++ <th>{{ . }}</th>
++ {{ end }}
++ </tr>
++ </thead>
++ <tbody>
++ {{ range $list }}
++ <tr>
++ {{ range $k, $v := . }}
++ {{ $.Scratch.Set $k $v }}
++ {{ end }}
++ {{ range $k, $v := $fields }}
++ <td>
++ {{ $tdContent := $.Scratch.Get . }}
++ {{ if eq $k 3 }}
++ {{ printf "%v" $tdContent |
++ strings.ReplaceRE `\[` "<ol><li>" |
++ strings.ReplaceRE `\s` "</li><li>" |
++ strings.ReplaceRE `\]` "</li></ol>" |
++ safeHTML
++ }}
++ {{ else }}
++ {{ $tdContent }}
++ {{ end }}
++ </td>
++ {{ end }}
++ </tr>
++ {{ end }}
++ </tbody>
++ </table>
++</div>
--- /dev/null
--- /dev/null
++{{ $package := (index .Params 0) }}
++{{ $listname := (index .Params 1) }}
++{{ $list := (index (index .Site.Data.docs $package) $listname) }}
++{{ $fields := after 2 .Params }}
++
++
++<div class="overflow-x-auto">
++ <table>
++ <thead>
++ <tr>
++ {{ range $fields }}
++ {{ $s := . }}
++ {{ if eq $s "_key" }}
++ {{ $s = "type" }}
++ {{ end }}
++ <th>{{ $s }}</th>
++ {{ end }}
++ </tr>
++ </thead>
++ <tbody>
++ {{ range $k1, $v1 := $list }}
++ <tr>
++ {{ range $k2, $v2 := . }}
++ {{ $.Scratch.Set $k2 $v2 }}
++ {{ end }}
++ {{ range $fields }}
++ {{ $s := "" }}
++ {{ if eq . "_key" }}
++ {{ $s = $k1 }}
++ {{ else }}
++ {{ $s = $.Scratch.Get . }}
++ {{ end }}
++ <td>{{ $s }}</td>
++ {{ end }}
++ </tr>
++ {{ end }}
++ </tbody>
++ </table>
++</div>
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders a callout indicating the version in which a feature was deprecated.
++
++Include descriptive text between the opening and closing tags, or omit the
++descriptive text and call the shortcode with a self-closing tag.
++
++@param {string} 0 The semantic version string, with or without a leading v.
++
++@example {{< deprecated-in 0.144.0 />}}
++
++@example {{< deprecated-in 0.144.0 >}}
++ Some descriptive text here.
++ {{< /deprecated-in >}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- with $version := .Get 0 | strings.TrimLeft "vV" }}
++ {{- $href := printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }}
++ {{- $inner := strings.TrimSpace $.Inner }}
++ {{- $text := printf "Deprecated in [v%s](%s)\n\n%s" $version $href $inner | $.Page.RenderString (dict "display" "block") }}
++ {{- partial "layouts/blocks/alert.html" (dict
++ "color" "orange"
++ "icon" "exclamation"
++ "text" $text
++ )
++ }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a single positional parameter indicating version. See %s" .Name .Position }}
++{{- end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders an absolute URL to the source code for an embedded template.
++
++Accepts either positional or named parameters, and depends on the
++embedded_templates.toml file in the data directory.
++
++@param {string} filename The embedded template's file name, excluding extension.
++
++@example {{% et robots.txt %}}
++@example {{% et filename=robots.txt %}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- with $filename := or (.Get "filename") (.Get 0) }}
++ {{- with site.Data.embedded_template_urls }}
++ {{- with index . $filename }}
++ {{- urls.JoinPath site.Data.embedded_template_urls.base_url . }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find a URL for the embedded template named %q. Check the name. See %s" $.Name $filename $.Position }}
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find the embedded_template_urls data file in the site's data directory. See %s" $.Name $.Position }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcodes requires a named or positional parameter, the file name of the embedded template, excluding its extension. See %s" .Name .Position }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- /*
++Renders the definition of the given glossary term.
++
++@param {string} (.Get 0) The glossary term.
++
++@example {{% glossary-term float %}}
++@example {{% glossary-term "floating point" %}}
++*/ -}}
++{{- with .Get 0 }}
++ {{- $path := printf "/quick-reference/glossary/%s" (urlize .) }}
++ {{- with site.GetPage $path }}
++{{ .RenderShortcodes }}{{/* Do not indent. */}}
++ {{- else }}
++ {{- errorf "The glossary term (%s) shortcode was unable to find %s: see %s" $.Name $path $.Position }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The glossary term (%s) shortcode requires one positional parameter: see %s" $.Name $.Position }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{- /*
++Renders the glossary of terms.
++
++When you call this shortcode using the {{% %}} notation, the glossary terms are
++Markdown headings (level 6) which means they are members of .Fragments. This
++allows the link render hook to verify links to glossary terms.
++
++Yes, the terms themselves are pages, but we don't want to link to the pages, at
++least not right now. Instead, we want to link to the ids rendered by this
++shortcode.
++
++@example {{% glossary %}}
++*/ -}}
++{{- $path := "/quick-reference/glossary" }}
++{{- with site.GetPage $path }}
++
++ {{- /* Build and render alphabetical index. */}}
++ {{- $m := dict }}
++ {{- range $p := .Pages.ByTitle }}
++ {{- $k := substr .Title 0 1 | strings.ToUpper }}
++ {{- if index $m $k }}
++ {{- continue }}
++ {{- end }}
++ {{- $anchor := path.BaseName .Path | anchorize }}
++ {{- $m = merge $m (dict $k $anchor) }}
++ {{- end }}
++ {{- range $k, $v := $m }}
++[{{ $k }}](#{{ $v }}) {{/* Do not indent. */}}
++ {{- end }}
++
++ {{/* Render glossary terms. */}}
++ {{- range $p := .Pages.ByTitle }}
++{{ .Title }}{{/* Do not indent. */}}
++: {{ .RawContent | strings.TrimSpace | safeHTML }}{{/* Do not indent. */}}
++ {{ with .Params.reference }}
++ {{- $destination := "" }}
++ {{- with $u := urls.Parse . }}
++ {{- if $u.IsAbs }}
++ {{- $destination = $u.String }}
++ {{- else }}
++ {{- with site.GetPage $u.Path }}
++ {{- $destination = .RelPermalink }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find the reference link %s: see %s" $.Name . $p.String }}
++ {{- end }}
++ {{- end }}
++ {{- end }}
++: See [details]({{ $destination }}).{{/* Do not indent. */}}
++ {{- end }}
++ {{ end }}
++
++{{- else }}
++ {{- errorf "The %q shortcode was unable to get %s: see %s" .Name $path .Position}}
++{{- end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Returns syntax-highlighted code from the given text.
++
++This is useful as a terse way to highlight inline code snippets. Calling the
++highlight shortcode for inline snippets is verbose.
++
++@example This is {{< hl python >}}inline{{< /hl >}} code.
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- $code := .Inner | strings.TrimSpace }}
++{{- $lang := or (.Get 0) "go" }}
++{{- $opts := dict "hl_inline" true "noClasses" true }}
++{{- transform.Highlight $code $lang $opts }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders the given image using the given filter, if any.
++
++When using the text filter, provide the arguments in this order:
++
++0. The text
++1. The horizontal offset, in pixels, relative to the left of the image (default 20)
++2. The vertical offset, in pixels, relative to the top of the image (default 20)
++3. The font size in pixels (default 64)
++4. The line height (default 1.2)
++5. The font color (default #ffffff)
++
++When using the padding filter, provide all arguments in this order:
++
++0. Padding top
++1. Padding right
++2. Padding bottom
++3. Padding right
++4. Canvas color
++
++@param {string} src The path to the image which must be a remote, page, or global resource.
++@param {string} [filter] The filter to apply to the image (case-insensitive).
++@param {string} [filterArgs] A comma-delimited list of arguments to pass to the filter.
++@param {bool} [example=false] If true, renders a before/after example.
++@param {int} [exampleWidth=384] Image width, in pixels, when rendering a before/after example.
++
++@example {{< img src="zion-national-park.jpg" >}}
++@example {{< img src="zion-national-park.jpg" alt="Zion National Park" >}}
++
++@example {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="grayscale"
++ >}}
++
++@example {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="process"
++ filterArgs="resize 400x webp"
++ >}}
++
++@example {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="colorize"
++ filterArgs="180,50,20"
++ >}}
++
++@example {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="grayscale"
++ example=true
++ >}}
++
++@example {{< img
++ src="zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="grayscale"
++ example=true
++ exampleWidth=400
++ >}}
++
++@example {{< img
++ src="images/examples/zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="Text"
++ filterArgs="Zion National Park,25,250,56"
++ example=true
++ >}}
++
++@example {{< img
++ src="images/examples/zion-national-park.jpg"
++ alt="Zion National Park"
++ filter="Padding"
++ filterArgs="20,50,20,50,#0705"
++ example=true
++ >}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- /* Initialize. */}}
++{{- $alt := "" }}
++{{- $src := "" }}
++{{- $filter := "" }}
++{{- $filterArgs := slice }}
++{{- $example := false }}
++{{- $exampleWidth := 384 }}
++
++{{- /* Default values to use with the text filter. */}}
++{{ $textFilterOpts := dict
++ "xOffset" 20
++ "yOffset" 20
++ "fontSize" 64
++ "lineHeight" 1.2
++ "fontColor" "#ffffff"
++ "fontPath" "https://github.com/google/fonts/raw/refs/heads/main/ofl/lato/Lato-Regular.ttf"
++}}
++
++{{- /* Get and validate parameters. */}}
++{{- with .Get "alt" }}
++ {{- $alt = . }}
++{{- end }}
++
++{{- with .Get "src" }}
++ {{- $src = . }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a file parameter. See %s" .Name .Position }}
++{{- end }}
++
++{{- with .Get "filter" }}
++ {{- $filter = . | lower }}
++{{- end }}
++
++{{- $validFilters := slice
++ "autoorient" "brightness" "colorbalance" "colorize" "contrast" "dither"
++ "gamma" "gaussianblur" "grayscale" "hue" "invert" "mask" "none" "opacity"
++ "overlay" "padding" "pixelate" "process" "saturation" "sepia" "sigmoid" "text"
++ "unsharpmask"
++}}
++
++{{- with $filter }}
++ {{- if not (in $validFilters .) }}
++ {{- errorf "The filter passed to the %q shortcode is invalid. The filter must be one of %s. See %s" $.Name (delimit $validFilters ", " ", or ") $.Position }}
++ {{- end }}
++{{- end }}
++
++{{- with .Get "filterArgs" }}
++ {{- $filterArgs = split . "," }}
++ {{- $filterArgs = apply $filterArgs "trim" "." " " }}
++{{- end }}
++
++{{- if in (slice "false" false 0) (.Get "example") }}
++ {{- $example = false }}
++{{- else if in (slice "true" true 1) (.Get "example") }}
++ {{- $example = true }}
++{{- end }}
++
++{{- with .Get "exampleWidth" }}
++ {{- $exampleWidth = . | int }}
++{{- end }}
++
++{{- /* Get image. */}}
++{{- $ctx := dict "page" .Page "src" $src "name" .Name "position" .Position }}
++{{- $i := partial "inline/get-resource.html" $ctx }}
++
++{{- /* Resize if rendering before/after examples. */}}
++{{- if $example }}
++ {{- $i = $i.Resize (printf "%dx" $exampleWidth) }}
++{{- end }}
++
++{{- /* Create filter. */}}
++{{- $f := "" }}
++{{- $ctx := dict "filter" $filter "args" $filterArgs "name" .Name "position" .Position }}
++{{- if eq $filter "autoorient" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.AutoOrient }}
++{{- else if eq $filter "brightness" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Brightness (index $filterArgs 0) }}
++{{- else if eq $filter "colorbalance" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage red" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage green" "argValue" (index $filterArgs 1) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage blue" "argValue" (index $filterArgs 2) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.ColorBalance (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }}
++{{- else if eq $filter "colorize" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "hue" "argValue" (index $filterArgs 0) "min" 0 "max" 360) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "saturation" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 2) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Colorize (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }}
++{{- else if eq $filter "contrast" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Contrast (index $filterArgs 0) }}
++{{- else if eq $filter "dither" }}
++ {{- $f = images.Dither }}
++{{- else if eq $filter "gamma" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "gamma" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Gamma (index $filterArgs 0) }}
++{{- else if eq $filter "gaussianblur" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.GaussianBlur (index $filterArgs 0) }}
++{{- else if eq $filter "grayscale" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Grayscale }}
++{{- else if eq $filter "hue" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "shift" "argValue" (index $filterArgs 0) "min" -180 "max" 180) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Hue (index $filterArgs 0) }}
++{{- else if eq $filter "invert" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Invert }}
++{{- else if eq $filter "mask" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }}
++ {{- $maskImage := partial "inline/get-resource.html" $ctx }}
++ {{- $f = images.Mask $maskImage }}
++{{- else if eq $filter "opacity" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "opacity" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Opacity (index $filterArgs 0) }}
++{{- else if eq $filter "overlay" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }}
++ {{- $overlayImg := partial "inline/get-resource.html" $ctx }}
++ {{- $f = images.Overlay $overlayImg (index $filterArgs 1 | float ) (index $filterArgs 2 | float) }}
++{{- else if eq $filter "padding" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 5) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Padding
++ (index $filterArgs 0 | int)
++ (index $filterArgs 1 | int)
++ (index $filterArgs 2 | int)
++ (index $filterArgs 3 | int)
++ (index $filterArgs 4)
++ }}
++{{- else if eq $filter "pixelate" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "size" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Pixelate (index $filterArgs 0) }}
++{{- else if eq $filter "process" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $f = images.Process (index $filterArgs 0) }}
++{{- else if eq $filter "saturation" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Saturation (index $filterArgs 0) }}
++{{- else if eq $filter "sepia" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Sepia (index $filterArgs 0) }}
++{{- else if eq $filter "sigmoid" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 2) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "midpoint" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "factor" "argValue" (index $filterArgs 1) "min" -10 "max" 10) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.Sigmoid (index $filterArgs 0) (index $filterArgs 1) }}
++{{- else if eq $filter "text" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $ctx := dict "src" $textFilterOpts.fontPath "name" .Name "position" .Position }}
++ {{- $font := or (partial "inline/get-resource.html" $ctx) }}
++ {{- $fontSize := or (index $filterArgs 3 | int) $textFilterOpts.fontSize }}
++ {{- $lineHeight := math.Max (or (index $filterArgs 4 | float) $textFilterOpts.lineHeight) 1 }}
++ {{- $opts := dict
++ "x" (or (index $filterArgs 1 | int) $textFilterOpts.xOffset)
++ "y" (or (index $filterArgs 2 | int) $textFilterOpts.yOffset)
++ "size" $fontSize
++ "linespacing" (mul (sub $lineHeight 1) $fontSize)
++ "color" (or (index $filterArgs 5) $textFilterOpts.fontColor)
++ "font" $font
++ }}
++ {{- $f = images.Text (index $filterArgs 0) $opts }}
++{{- else if eq $filter "unsharpmask" }}
++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }}
++ {{- template "validate-arg-count" $ctx }}
++ {{- $filterArgs = apply $filterArgs "float" "." }}
++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 500) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "amount" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $ctx = merge $ctx (dict "argName" "threshold" "argValue" (index $filterArgs 2) "min" 0 "max" 1) }}
++ {{- template "validate-arg-value" $ctx }}
++ {{- $f = images.UnsharpMask (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }}
++{{- end }}
++
++{{- /* Apply filter. */}}
++{{- $fi := $i }}
++{{- with $f }}
++ {{- $fi = $i.Filter . }}
++{{- end }}
++
++{{- /* Render. */}}
++{{- $class := "border-1 border-gray-300 dark:border-gray-500" }}
++{{- if $example }}
++ <p>Original</p>
++ <img
++ class="{{ $class }}"
++ src="{{ $i.RelPermalink }}"
++ alt="{{ $alt }}">
++ <p>Processed</p>
++ <img
++ class="{{ $class }}"
++ src="{{ $fi.RelPermalink }}"
++ alt="{{ $alt }}">
++{{- else -}}
++ <img
++ src="{{ $fi.RelPermalink }}"
++ alt="{{ $alt }}">
++{{- end }}
++
++{{- define "validate-arg-count" }}
++ {{- $msg := "When using the %q filter, the %q shortcode requires an args parameter with %d %s. See %s" }}
++ {{- if lt (len .args) .argsRequired }}
++ {{- $text := "values" }}
++ {{- if eq 1 .argsRequired }}
++ {{- $text = "value" }}
++ {{- end }}
++ {{- errorf $msg .filter .name .argsRequired $text .position }}
++ {{- end }}
++{{- end }}
++
++{{- define "validate-arg-value" }}
++ {{- $msg := "The %q argument passed to the %q shortcode is invalid. Expected a value in the range [%v,%v], but received %v. See %s" }}
++ {{- if or (lt .argValue .min) (gt .argValue .max) }}
++ {{- errorf $msg .argName .name .min .max .argValue .position }}
++ {{- end }}
++{{- end }}
++
++{{- define "_partials/inline/get-resource.html" }}
++ {{- $r := "" }}
++ {{- $u := urls.Parse .src }}
++ {{- $msg := "The %q shortcode was unable to resolve %s. See %s" }}
++ {{- if $u.IsAbs }}
++ {{- with try (resources.GetRemote $u.String) }}
++ {{- with .Err }}
++ {{- errorf "%s" . }}
++ {{- else with .Value }}
++ {{- /* This is a remote resource. */}}
++ {{- $r = . }}
++ {{- else }}
++ {{- errorf $msg $.name $u.String $.position }}
++ {{- end }}
++ {{- end }}
++ {{- else }}
++ {{- with .page.Resources.Get (strings.TrimPrefix "./" $u.Path) }}
++ {{- /* This is a page resource. */}}
++ {{- $r = . }}
++ {{- else }}
++ {{- with resources.Get $u.Path }}
++ {{- /* This is a global resource. */}}
++ {{- $r = . }}
++ {{- else }}
++ {{- errorf $msg $.name $u.Path $.position }}
++ {{- end }}
++ {{- end }}
++ {{- end }}
++ {{- return $r }}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders the given image using the given process specification.
++
++@param {string} path The path to the image, either a page resource or a global resource.
++@param {string} spec The image processing specification.
++@param {string} alt The alt attribute of the img element.
++
++@example {{< imgproc path="sunset.jpg" spec="resize 300x" alt="A sunset" >}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- with $.Get "path" }}
++ {{- with $i := or ($.Page.Resources.Get .) (resources.Get .) }}
++ {{- with $spec := $.Get "spec" }}
++ {{- with $i.Process . }}
++ <figure>
++ <img
++ src="{{ .RelPermalink }}"
++ width="{{ .Width }}"
++ height="{{ .Height }}"
++ alt="{{ $.Get `alt` }}">
++ <figcaption class="not-prose text-sm">
++ {{- with $.Inner }}
++ {{ . }}
++ {{- else }}
++ {{ $spec }}
++ {{- end }}
++ </figcaption>
++ </figure>
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode requires a 'spec' argument containing the image processing specification. See %s" $.Name $.Position }}
++ {{- end }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a 'path' argument indicating the image path. The image must be a page resource or a global resource. See %s" $.Name $.Position }}
++{{- end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders the page using the RenderShortcode method on the Page object.
++
++You must call this shortcode using the {{% %}} notation.
++
++@param {string} (positional parameter 0) The path to the page, relative to the content directory.
++
++@example {{% include "functions/_common/glob-patterns" %}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- with .Get 0 }}
++ {{- with or ($.Page.GetPage .) (site.GetPage .) }}
++ {{- .RenderShortcodes }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a positional parameter indicating the path of the file to include. See %s" .Name .Position }}
++{{- end }}
--- /dev/null
--- /dev/null
++{{- /*
++Renders a description list of the pages in the given section.
++
++Render a subset of the pages in the section by specifying a predefined filter,
++and whether to include those pages.
++
++Filters are defined in the data directory, in the file named page_filters. Each
++filter is an array of paths to a file, relative to the root of the content
++directory. Hugo will throw an error if the specified filter does not exist, or
++if any of the pages in the filter do not exist.
++
++@param {string} path The path to the section.
++@param {string} [filter=""] The name of filter list.
++@param {string} [filterType=""] The type of filter, either include or exclude.
++@param {string} [titlePrefix=""] The string to prepend to the link title.
++
++@example {{< list-pages-in-section path=/methods/resources >}}
++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude >}}
++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude titlePrefix=foo >}}
++*/}}
++
++{{/* Initialize. */}}
++{{ $filter := or "" (.Get "filter" | lower) }}
++{{ $filterType := or (.Get "filterType") "none" | lower }}
++{{ $filteredPages := slice }}
++{{ $titlePrefix := or (.Get "titlePrefix") "" }}
++
++{{/* Build slice of filtered pages. */}}
++{{ with $filter }}
++ {{ with index site.Data.page_filters . }}
++ {{ range . }}
++ {{ with site.GetPage . }}
++ {{ $filteredPages = $filteredPages | append . }}
++ {{ else }}
++ {{ errorf "The %q shortcode was unable to find %q as specified in the page_filters data file. See %s" $.Name . $.Position }}
++ {{ end }}
++ {{ end }}
++ {{ else }}
++ {{ errorf "The %q shortcode was unable to find the %q filter in the page_filters data file. See %s" $.Name . $.Position }}
++ {{ end }}
++{{ end }}
++
++{{/* Render. */}}
++{{ with $sectionPath := .Get "path" }}
++ {{ with site.GetPage . }}
++ {{ with .RegularPages }}
++ {{ range $page := .ByTitle }}
++ {{ if or
++ (and (eq $filterType "include") (in $filteredPages $page))
++ (and (eq $filterType "exclude") (not (in $filteredPages $page)))
++ (eq $filterType "none")
++ }}
++ {{ $linkTitle := .LinkTitle }}
++ {{ with $titlePrefix }}
++ {{ $linkTitle = printf "%s%s" . $linkTitle }}
++ {{ end }}
++[{{ $linkTitle }}]({{ $page.RelPermalink }}){{/* Do not indent. */}}
++: {{ $page.Description }}{{/* Do not indent. */}}
++ {{ end }}
++ {{ end }}
++ {{ else }}
++ {{ warnf "The %q shortcode found no pages in the %q section. See %s" $.Name $sectionPath $.Position }}
++ {{ end }}
++ {{ else }}
++ {{ errorf "The %q shortcode was unable to find %q. See %s" $.Name $sectionPath $.Position }}
++ {{ end }}
++{{ else }}
++ {{ errorf "The %q shortcode requires a 'path' parameter indicating the path to the section. See %s" $.Name $.Position }}
++{{ end }}
--- /dev/null
--- /dev/null
++For a more flexible approach to configuring this directory, consult the section
++on [module mounts](/configuration/module/#mounts).
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders a callout or badge indicating the version in which a feature was added.
++
++To render a callout, include descriptive text between the opening and closing
++tags. To render a badge,omit the descriptive text and call the shortcode with a
++self-closing tag.
++
++When comparing the current version to the specified version, the "new in"
++button will be hidden if any of the following conditions is true:
++
++- The major version difference exceeds the majorVersionDiffThreshold
++- The minor version difference exceeds the minorVersionDiffThreshold
++
++@param {string} 0 The semantic version string, with or without a leading v.
++
++@example {{< new-in 0.100.0 />}}
++
++@example {{{< new-in 0.100.0 >}}
++ Some descriptive text here.
++ {{< /new-in >}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- $majorVersionDiffThreshold := 0 }}
++{{- $minorVersionDiffThreshold := 30 }}
++{{- $displayExpirationWarning := true }}
++
++{{- with $version := .Get 0 | strings.TrimLeft "vV" }}
++ {{- $majorVersionDiff := sub (index (split hugo.Version ".") 0 | int) (index (split $version ".") 0 | int) }}
++ {{- $minorVersionDiff := sub (index (split hugo.Version ".") 1 | int) (index (split $version ".") 1 | int) }}
++ {{- if or (gt $majorVersionDiff $majorVersionDiffThreshold) (gt $minorVersionDiff $minorVersionDiffThreshold) }}
++ {{- if $displayExpirationWarning }}
++ {{- warnf "This call to the %q shortcode should be removed: %s. The button is now hidden because the specified version (%s) is older than the display threshold." $.Name $.Position $version }}
++ {{- end }}
++ {{- else }}
++ {{- $href := printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }}
++ {{- with $.Inner }}
++ {{- $inner := strings.TrimSpace . }}
++ {{- $text := printf "New in [v%s](%s)\n\n%s" $version $href $inner | $.Page.RenderString (dict "display" "block") }}
++ {{ partial "layouts/blocks/alert.html" (dict
++ "color" "green"
++ "icon" "exclamation"
++ "text" $text
++ )
++ }}
++ {{- else }}
++ <span
++ class="not-prose inline-flex items-center px-2 mr-1 rounded text-sm font-medium bg-green-200 dark:bg-green-400 fill-green-600">
++ <svg class="mr-1.5 h-2 w-2" viewBox="0 0 8 8">
++ <circle cx="4" cy="4" r="3" />
++ </svg>
++ <a
++ class="text-green-800 dark:text-black hover:text-green-600 no-underline"
++ href="{{ $href }}"
++ target="_blank">
++ New in
++ v{{ $version }}
++ </a>
++ </span>
++ {{- end }}
++ {{- end }}
++{{- else }}
++ {{- errorf "The %q shortcode requires a single positional parameter indicating version. See %s" .Name .Position }}
++{{- end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{- /*
++Renders a responsive grid of the configuration keys that can be defined
++separately for each language.
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- $siteConfigKeys := slice
++ (dict "baseURL" "/configuration/all/#baseurl")
++ (dict "buildDrafts" "/configuration/all/#builddrafts")
++ (dict "buildExpired" "/configuration/all/#buildexpired")
++ (dict "buildFuture" "/configuration/all/#buildfuture")
++ (dict "canonifyURLs" "/configuration/all/#canonifyurls")
++ (dict "capitalizeListTitles" "/configuration/all/#capitalizelisttitles")
++ (dict "contentDir" "/configuration/all/#contentdir")
++ (dict "copyright" "/configuration/all/#copyright")
++ (dict "disableAliases" "/configuration/all/#disablealiases")
++ (dict "disableHugoGeneratorInject" "/configuration/all/#disablehugogeneratorinject")
++ (dict "disableKinds" "/configuration/all/#disablekinds")
++ (dict "disableLiveReload" "/configuration/all/#disablelivereload")
++ (dict "disablePathToLower" "/configuration/all/#disablepathtolower")
++ (dict "enableEmoji " "/configuration/all/#enableemoji")
++ (dict "frontmatter" "/configuration/front-matter/")
++ (dict "hasCJKLanguage" "/configuration/all/#hascjklanguage")
++ (dict "languageCode" "/configuration/all/#languagecode")
++ (dict "mainSections" "/configuration/all/#mainsections")
++ (dict "markup" "/configuration/markup/")
++ (dict "mediaTypes" "/configuration/media-types/")
++ (dict "menus" "/configuration/menus/")
++ (dict "outputFormats" "/configuration/output-formats")
++ (dict "outputs" "/configuration/outputs/")
++ (dict "page" "/configuration/page/")
++ (dict "pagination" "/configuration/pagination/")
++ (dict "params" "/configuration/params/")
++ (dict "permalinks" "/configuration/permalinks/")
++ (dict "pluralizeListTitles" "/configuration/all/#pluralizelisttitles")
++ (dict "privacy" "/configuration/privacy/")
++ (dict "refLinksErrorLevel" "/configuration/all/#reflinkserrorlevel")
++ (dict "refLinksNotFoundURL" "/configuration/all/#reflinksnotfoundurl")
++ (dict "related" "/configuration/related-content/")
++ (dict "relativeURLs" "/configuration/all/#relativeurls")
++ (dict "removePathAccents" "/configuration/all/#removepathaccents")
++ (dict "renderSegments" "/configuration/all/#rendersegments")
++ (dict "sectionPagesMenu" "/configuration/all/#sectionpagesmenu")
++ (dict "security" "/configuration/security/")
++ (dict "services" "/configuration/services/")
++ (dict "sitemap" "/configuration/sitemap/")
++ (dict "staticDir" "/configuration/all/#staticdir")
++ (dict "summaryLength" "/configuration/all/#summarylength")
++ (dict "taxonomies" "/configuration/taxonomies/")
++ (dict "timeZone" "/configuration/all/#timezone")
++ (dict "title" "/configuration/all/#title")
++ (dict "titleCaseStyle" "/configuration/all/#titlecasestyle")
++}}
++
++{{- $a := len $siteConfigKeys }}
++{{- $b := math.Ceil (div $a 2.) }}
++{{- $c := math.Ceil (div $a 3.) }}
++
++
++<div
++ class="grid grid-flow-col grid-rows-{{ $a }} sm:grid-rows-{{ $b }} md:grid-rows-{{ $c }} gap-1">
++ {{- range $siteConfigKeys }}
++ {{ range $k, $v := . }}
++ {{ $u := urls.Parse $v }}
++ {{ if not (site.GetPage $u.Path) }}
++ {{ errorf "The %q shorcode was unable to find %s. See %s." $.Name $u.Path $.Position }}
++ {{ end }}
++ <a href="{{ $v | relLangURL }}"><code>{{ $k }}</code></a>
++ {{ end }}
++ {{- end }}
++</div>
--- /dev/null
--- /dev/null
++{{- /*
++Renders the child sections of the given top-level section, listing each child's
++immediate descendants.
++
++@param {string} section The top-level section to render.
++
++@example {{% quick-reference section="/functions" %}}
++*/ -}}
++{{ $section := "" }}
++{{ with .Get "section" }}
++ {{ $section = . }}
++{{ else }}
++ {{ errorf "The %q shortcode requires a 'section' parameter. See %s" .Name .Position }}
++{{ end }}
++
++{{ with site.GetPage $section }}
++ {{ range .Sections }}
++## {{ .LinkTitle }}{{/* Do not indent. */}}
++{{ .Description }}{{/* Do not indent. */}}
++ {{ .Content }}
++ {{ with .Pages }}
++ {{ range . }}
++[{{ .LinkTitle }}]({{ .RelPermalink }}){{/* Do not indent. */}}
++: {{ .Description }}{{/* Do not indent. */}}
++ {{ end }}
++ {{ end }}
++ {{ end }}
++{{ else }}
++ {{ errorf "The %q shortcodes was unable to find the %q section. See %s" .Name $section .Position }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{/* prettier-ignore-start */ -}}
++{{/*
++Renders a comma-separated list of links to the root key configuration pages.
++
++@example {{< root-configuration-keys >}}
++*/ -}}
++{{/* prettier-ignore-end */ -}}
++{{- /* Create scratch map of key:filename. */}}
++{{- $s := newScratch }}
++{{- range $k, $v := site.Data.docs.config }}
++ {{- if or (reflect.IsMap .) (reflect.IsSlice .) }}
++ {{- $s.Set $k ($k | humanize | anchorize) }}
++ {{- end }}
++{{- end }}
++
++{{/* Deprecated. */}}
++{{- $s.Delete "author" }}
++
++{{/* Use mounts instead. */}}
++{{- $s.Delete "staticDir" }}
++{{- $s.Delete "ignoreFiles" }}
++
++{{/* This key is "HTTPCache" not "httpCache". */}}
++{{- $s.Set "HTTPCache" "http-cache" }}
++
++{{/* This key is "frontmatter" not "frontMatter" */}}
++{{- $s.Set "frontmatter" "front-matter" }}
++
++{{/* The page title is "Related content" not "related". */}}
++{{- $s.Set "related" "related-content" }}
++
++{{/* It can be configured as bool or map; we want to show map. */}}
++{{- $s.Set "uglyURLs" "ugly-urls" }}
++
++{{- $links := slice }}
++{{- range $k, $v := $s.Values }}
++ {{- $path := printf "/configuration/%s" $v }}
++ {{- with site.GetPage $path }}
++ {{- $links = $links | append (printf "<a href=%q><code>%s</code></a>" .RelPermalink $k) }}
++ {{- else }}
++ {{- errorf "The %q shortcode was unable to find the page %s. See %s." $.Name $path $.Position }}
++ {{- end }}
++{{- end }}
++
++{{- delimit $links ", " ", and " | safeHTML -}}
--- /dev/null
--- /dev/null
++{{- /*
++Renders a gallery a Chroma syntax highlighting styles.
++
++@example {{% syntax-highlighting-styles %}}
++*/ -}}
++{{- $examples := slice }}
++
++{{- /* Example: css */}}
++{{- $example := dict "lang" "css" "code" `
++body {
++ font-size: 16px; /* comment */
++}
++`}}
++{{- $examples = $examples | append $example }}
++
++{{- /* Example: html */}}
++{{- $example = dict "lang" "html" "code" `
++<a href="/about.html">Example</a> <!-- comment -->
++`}}
++{{- $examples = $examples | append $example }}
++
++{{- /* Example: go-html-template */}}
++{{- $example = dict "lang" "go-html-template" "code" `
++{{ with $.Page.Params.content }}
++ {{ . | $.Page.RenderString }} {{/* comment */}}
++{{ end }}
++`}}
++{{- $examples = $examples | append $example }}
++
++{{- /* Example: javascript */}}
++{{- $example = dict "lang" "javascript" "code" `
++if ([1,"one",2,"two"].includes(value)){
++ console.log("Number is either 1 or 2."); // comment
++}
++`}}
++{{- $examples := $examples | append $example }}
++
++{{- /* Example: markdown */}}
++{{- $example = dict "lang" "markdown" "code" `
++{{< figure src="kitten.jpg" >}}
++[example](https://example.org "An example") <!-- comment -->
++`}}
++{{- $examples := $examples | append $example }}
++
++{{- /* Example: toml */}}
++{{- $example = dict "lang" "toml" "code" `
++[params]
++bool = true # comment
++string = 'foo'
++`}}
++{{- $examples := $examples | append $example }}
++
++{{- /* Render */}}
++{{- with site.Data.docs.chroma.styles }}
++ {{- range $style := . }}
++
++### {{ $style }} {class="!mt-7 !mb-6"}{{/* Do not indent. */}}
++
++ {{- range $examples }}
++
++{{ .lang }}{{/* Do not indent. */}}
++{class="text-sm !-mt-3 !-mb-5"}{{/* Do not indent. */}}
++
++```{{ .lang }} {noClasses=true style="{{ $style }}"}{{/* Do not indent. */}}
++{{- .code | safeHTML -}}{{/* Do not indent. */}}
++```{{/* Do not indent. */}}
++
++ {{- end }}
++ {{- end }}
++{{- end }}
--- /dev/null
--- /dev/null
++<!doctype html>
++<html
++ class="h-full antialiased scheme-light dark:scheme-dark"
++ lang="{{ or site.Language.LanguageCode `en-US` }}">
++ <head>
++ <meta charset="utf-8">
++ <title>
++ {{ .Title }}
++ </title>
++ <style>
++ [x-cloak] {
++ display: none !important;
++ }
++ </style>
++ <meta
++ name="description"
++ content="{{ .Description | default site.Params.description }}">
++ {{ partial "layouts/head/head-js.html" . }}
++ {{ with (templates.Defer (dict "key" "global")) }}
++ {{ $t := debug.Timer "tailwindcss" }}
++ {{ with resources.Get "css/styles.css" }}
++ {{ $opts := dict
++ "inlineImports" true
++ "minify" (not hugo.IsDevelopment)
++ }}
++ {{ with . | css.TailwindCSS $opts }}
++ {{ partial "helpers/linkcss.html" (dict "r" .) }}
++ {{ end }}
++ {{ end }}
++ {{ $t.Stop }}
++ {{ end }}
++ {{ $noop := .WordCount }}
++ {{ if .Page.Store.Get "hasMath" }}
++ <link
++ href="https://cdn.jsdelivr.net/npm/katex@0.16.21/dist/katex.min.css"
++ rel="stylesheet">
++ {{ end }}
++ {{ partial "layouts/head/head.html" . }}
++ </head>
++ <body
++ class="flex flex-col min-h-full bg-white dark:bg-blue-950 kind-{{ .Kind }}">
++ {{ partial "layouts/hooks/body-start.html" . }}
++ {{/* Layout. */}}
++ {{ block "header" . }}
++ {{ partial "layouts/header/header.html" . }}
++ {{ end }}
++ {{ block "subheader" . }}
++ {{ end }}
++ {{ block "hero" . }}
++ {{ end }}
++ <div class="flex w-full xl:w-6xl h-full flex-auto mx-auto">
++ <main
++ class="flex-1 mx-auto lg:mx-0 w-full max-w-3x lg:max-w-3x pt-8 lg:pt-14 pb-20 px-main print:pt-0">
++ {{ partial "layouts/hooks/body-main-start.html" . }}
++ {{ block "main" . }}{{ end }}
++ </main>
++ {{ block "rightsidebar" . }}
++ <aside
++ class="py-15 ml-4 xl:ml-12 w-60 hidden lg:relative lg:block lg:flex-none">
++ {{ block "rightsidebar_content" . }}{{ end }}
++ </aside>
++ {{ end }}
++ </div>
++ {{/* Common icons. */}}
++ {{ partial "layouts/icons.html" . }}
++ {{/* Common templates. */}}
++ {{ partial "layouts/templates.html" . }}
++ {{/* Footer. */}}
++ {{ block "footer" . }}
++ {{ partial "layouts/footer.html" . }}
++ {{ end }}
++ {{ partial "layouts/hooks/body-end.html" . }}
++ </body>
++</html>
--- /dev/null
--- /dev/null
++/*
++ X-Frame-Options: DENY
++ X-XSS-Protection: 1; mode=block
++ X-Content-Type-Options: nosniff
++ Referrer-Policy: origin-when-cross-origin
--- /dev/null
--- /dev/null
++{{ define "main" }}
++ <div class="flex flex-col w-full p-0 m-0">
++ {{ partial "layouts/home/opensource.html" . }}
++ <hr class="border-t border-gray-200 dark:border-gray-800 my-10 lg:my-14">
++ {{ partial "layouts/home/sponsors.html" (dict "ctx" . "gtag" "home" ) }}
++ <hr class="border-t border-gray-200 dark:border-gray-800 my-10 lg:my-14">
++ {{ partial "layouts/home/features.html" . }}
++ </div>
++{{ end }}
++
++{{ define "hero" }}
++ <div class="relative isolate px-6 lg:px-8">
++ <div class="mx-auto max-w-2xl pt-16">
++ <div class="text-center">
++ <img
++ src="{{ `images/hugo-logo-wide.svg`| relURL }}"
++ alt="Hugo Logo"
++ class="w-64 aspect-3/1 mx-auto mb-8">
++ <h1
++ class="text-4xl font-bold tracking-tight text-balance text-gray-900 dark:text-gray-300 sm:text-6xl">
++ The world’s fastest framework for building websites
++ </h1>
++ <div
++ class="mt-8 text-lg font-medium text-pretty text-gray-800 dark:text-gray-400 sm:text-xl/8">
++ Hugo is one of the most popular open-source static site generators.
++ With its amazing speed and flexibility, Hugo makes building websites
++ fun again.
++ </div>
++ <div class="mt-10 flex items-center justify-center gap-x-6">
++ {{ with site.GetPage "/getting-started" }}
++ <a
++ href="{{ .RelPermalink }}"
++ class="rounded-md uppercase tracking-wide bg-blue-600 hover:bg-blue-500 px-3.5 py-2.5 text-sm font-semibold text-white shadow-xs focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600"
++ >{{ .LinkTitle }}</a
++ >
++ {{ end }}
++ <div class="-my-5 mr-6 sm:mr-8 md:mr-0">
++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" true) }}
++ </div>
++ </div>
++ </div>
++ </div>
++ </div>
++{{ end }}
++
++{{ define "rightsidebar" }}
++ {{ printf "%c" '\u00A0' }}
++{{ end }}
++
++{{ define "leftsidebar" }}
++ {{ printf "%c" '\u00A0' }}
++{{ end }}
--- /dev/null
--- /dev/null
++# Netlify redirects. See https://www.netlify.com/docs/redirects/
++{{ range $p := .Site.Pages -}}
++{{ range .Aliases }}
++{{ . | printf "%-35s" }} {{ $p.RelPermalink -}}
++{{ end -}}
++{{- end -}}
--- /dev/null
--- /dev/null
++{{ define "main" }}
++ {{ $pages := "" }}
++ {{ if .IsPage }}
++ {{/* We currently have a slightly odd content structure with no top level /docs section. */}}
++ {{ $pages = .CurrentSection.Pages }}
++ {{ else }}
++ {{ $pages = .Pages }}
++ {{ if eq .Section "news" }}
++ {{ $pages = $pages.ByPublishDate.Reverse }}
++ {{ end }}
++ {{ end }}
++
++
++ <article class="">
++ {{ partial "layouts/docsheader.html" . }}
++ <div class="mt-6 sm:mt-8 grid grid-cols-2 xl:grid-cols-3 gap-4 min-h-40">
++ {{ range $pages }}
++ {{ if eq . $ }}
++ {{ continue }}
++ {{ end }}
++ <a
++ class="flex col-span-1 a--block cursor-pointer flex-col group border p-3 sm:p-4 hover:shadow-md dark:shadow-slate-800 border-gray-300 dark:border-gray-800 m-0"
++ href="{{ or .Params.permalink .RelPermalink }}">
++ {{ if .Params.show_publish_date }}
++ {{ with .PublishDate }}
++ <p
++ class="text-gray-500 dark:text-gray-400 text-sm/5 md:text-base/2 mb-2 sm:mb-4">
++ {{ partial "layouts/date.html" . }}
++ </p>
++ {{ end }}
++ {{ end }}
++ <h3
++ class="text-lg/6 md:text-2xl tracking-tight p-0 -mt-1 sm:mt-0 mb-1 sm:mb-2 text-primary group-hover:text-primary/70 overflow-hidden">
++ {{ .LinkTitle }}
++ </h3>
++
++ {{ with .Params.functions_and_methods.signatures }}
++ {{/* Set in functions and methods pages. */}}
++ {{ with $signature := index . 0 }}
++ {{ if $.Params.functions_and_methods.returnType }}
++ {{ $signature = printf "%s ⟼ %s" $signature $.context.Params.functions_and_methods.returnType }}
++ {{ end }}
++ <div
++ class="font-mono font-light text-sm whitespace-nowrap mb-2 sm:mb-4 p-2 bg-slate-50 dark:bg-slate-700 border-0 mr-8 overflow-x-auto">
++ {{- $signature -}}
++ </div>
++ {{ end }}
++ {{ end }}
++ <p
++ class="text-black dark:text-gray-100 leading-6 text-sm md:text-base three-lines-ellipsis">
++ {{ if and (eq .Section "commands") .IsPage }}
++ {{ $simpleCobraCommandShort := .RawContent | strings.ReplaceRE `(?s)^##\s.+?\n\n(.+?)\n\n.*` "$1" }}
++ {{ printf "%s." $simpleCobraCommandShort }}
++ {{ else }}
++ {{ (or .Params.description .Summary) | plainify | safeHTML }}
++ {{ end }}
++ </p>
++ {{ if and hugo.IsDevelopment site.Params.debug.display_page_metadata }}
++ {{ partial "helpers/debug/list-item-metadata.html" . }}
++ {{ end }}
++ </a>
++ {{ end }}
++ </div>
++ </article>
++{{ end }}
++
++{{ define "rightsidebar" }}
++ {{ printf "%c" '\u00A0' }}
++{{ end }}
--- /dev/null
--- /dev/null
++{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
++<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
++ <channel>
++ <title>Hugo News</title>
++ <description>Recent news about Hugo, a static site generator written in Go, optimized for speed and designed for flexibility.</description>
++ <link>{{ .Permalink }}</link>
++ <generator>Hugo {{ hugo.Version }}</generator>
++ <language>{{ or site.Language.LanguageCode site.Language.Lang }}</language>
++ {{- with site.Copyright }}
++ <copyright>{{ . }}</copyright>
++ {{- end }}
++ {{- with .OutputFormats.Get "rss" }}
++ {{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
++ {{- end }}
++ {{- $limit := cond (gt site.Config.Services.RSS.Limit 0) site.Config.Services.RSS.Limit 999 }}
++ {{- $pages := "" }}
++ {{- with site.GetPage "/news" }}
++ {{- $pages = .Pages.ByPublishDate.Reverse | first $limit }}
++ {{- else }}
++ {{- errorf "The list.rss.xml layout was unable to find the 'news' page." }}
++ {{- end }}
++ <lastBuildDate>{{ (index $pages 0).PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
++ {{- range $pages }}
++ <item>
++ <title>{{ .Title }}</title>
++ <link>{{ or .Params.permalink .Permalink }}</link>
++ <pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
++ <guid>{{ or .Params.permalink .Permalink }}</guid>
++ <description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
++ </item>
++ {{- end }}
++ </channel>
++</rss>
--- /dev/null
--- /dev/null
++{{ define "main" }}
++ {{ $ttop := debug.Timer "single" }}
++ <article class="max-w-5xl lg:max-w-3xl" id="article">
++ {{ partial "layouts/docsheader.html" . }}
++ <div class="content">
++ {{ with .Params.description }}
++ <div class="lead">
++ {{ . | markdownify }}
++ </div>
++ {{ end }}
++ {{ if .Params.show_publish_date }}
++ {{ with .PublishDate }}
++ <p
++ class="text-gray-500 dark:text-gray-400 text-sm/5 md:text-base/2 mb-2 sm:mb-4">
++ {{ partial "layouts/date.html" . }}
++ </p>
++ {{ end }}
++ {{ end }}
++ {{ $t := debug.Timer "single.categories" }}
++ {{ $categories := .GetTerms "categories" }}
++ {{ with $categories }}
++ <div class="mb-4 sm:mb-6 flex flex-wrap gap-2">
++ {{ range . }}
++ {{ $text := .LinkTitle }}
++ {{ $class := "" }}
++ {{ range (slice true false ) }}
++ {{ $color := partial "helpers/funcs/color-from-string.html" (dict "text" $text "dark" . "--single" "green" ) }}
++
++ {{ $prefix := "" }}
++ {{ if . }}
++ {{ $prefix = "dark:" }}
++ {{ end }}
++ {{ $class = printf "%sbg-%s-%d %stext-%s-%d border %sborder-%s-%d"
++ $prefix $color.color $color.shade1
++ $prefix $color.color $color.shade2
++ $prefix $color.color $color.shade3
++ }}
++ {{ end }}
++
++
++ <a
++ href="{{ .RelPermalink }}"
++ class="{{ $class }} text-xs h-auto tracking-widest uppercase font-light not-prose no-underline inline-block py-1 px-3 rounded-xl shadow-xs hover:opacity-80 hover:shadow-none">
++ {{ .LinkTitle }}
++ </a>
++ {{ end }}
++ </div>
++ {{ end }}
++ {{ $t.Stop }}
++
++ {{ if .Params.functions_and_methods.signatures }}
++ <div class="mb-4 not-prose">
++ {{- partial "docs/functions-signatures.html" . -}}
++ {{- partial "docs/functions-return-type.html" . -}}
++ {{- partial "docs/functions-aliases.html" . -}}
++ </div>
++ {{ end }}
++ {{ $t := debug.Timer "single.content" }}
++ {{ .Content }}
++ {{ $t.Stop }}
++ {{ $t := debug.Timer "single.page-edit" }}
++ {{ partial "layouts/page-edit.html" . }}
++ {{ $t.Stop }}
++ </div>
++ </article>
++ {{ $ttop.Stop }}
++{{ end }}
++
++{{ define "rightsidebar_content" }}
++ {{/* in-this-section.html depends on these being reneredc first. */}}
++ {{ $related := partial "layouts/related.html" . }}
++ {{ $toc := partial "layouts/toc.html" . }}
++ {{ if not .Params.hide_in_this_section }}
++ {{ partial "layouts/in-this-section.html" . }}
++ {{ end }}
++ {{ $related }}
++ {{ if $.Store.Get "hasToc" }}
++ {{ $toc }}
++ {{ end }}
++{{ end }}
--- /dev/null
- HUGO_VERSION = "0.145.0"
+[build]
+ publish = "public"
+ command = "hugo --gc --minify"
+
+ [build.environment]
++ HUGO_VERSION = "0.146.7"
+
+[context.production.environment]
+ HUGO_ENV = "production"
+ HUGO_ENABLEGITINFO = "true"
+
+[context.split1]
+ command = "hugo --gc --minify --enableGitInfo"
+
+ [context.split1.environment]
+ HUGO_ENV = "production"
+
+[context.deploy-preview]
+ command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL --enableGitInfo"
+
+[context.branch-deploy]
+ command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"
+
+[context.next.environment]
+ HUGO_ENABLEGITINFO = "true"
+
+[[headers]]
+ for = "/*.jpg"
+
+ [headers.values]
+ Cache-Control = "public, max-age=31536000"
+
+[[headers]]
+ for = "/*.png"
+
+ [headers.values]
+ Cache-Control = "public, max-age=31536000"
+
+[[headers]]
+ for = "/*.css"
+
+ [headers.values]
+ Cache-Control = "public, max-age=31536000"
+
+[[headers]]
+ for = "/*.js"
+
+ [headers.values]
+ Cache-Control = "public, max-age=31536000"
+
+[[headers]]
+ for = "/*.ttf"
+
+ [headers.values]
+ Cache-Control = "public, max-age=31536000"
--- /dev/null
--- /dev/null
++{
++ "name": "hugoDocs",
++ "version": "1.0.0",
++ "description": "",
++ "main": "index.js",
++ "scripts": {
++ "test": "echo \"Error: no test specified\" && exit 1"
++ },
++ "author": "",
++ "license": "",
++ "devDependencies": {
++ "@awmottaz/prettier-plugin-void-html": "~1.8.0",
++ "@tailwindcss/cli": "~4.1.0",
++ "@tailwindcss/typography": "~0.5.16",
++ "prettier": "~3.5.3",
++ "prettier-plugin-go-template": "~0.0.15",
++ "tailwindcss": "~4.1.0"
++ },
++ "dependencies": {
++ "@alpinejs/focus": "~3.14.9",
++ "@alpinejs/persist": "~3.14.9",
++ "@hotwired/turbo": "~8.0.13",
++ "alpinejs": "~3.14.9"
++ }
++}