--- /dev/null
- : Do not render the page to disk, but include it in all page collections.
+---
+title: Build options
+description: Build options help define how Hugo must treat a given page when building the site.
+categories: [content management,fundamentals]
+keywords: [build,content,front matter, page resources]
+menu:
+ docs:
+ parent: content-management
+ weight: 70
+weight: 70
+toc: true
+aliases: [/content/build-options/]
+---
+
+Build options are stored in a reserved front matter object named `_build` with these defaults:
+
+{{< code-toggle file=content/example/index.md fm=true >}}
+[_build]
+list = 'always'
+publishResources = true
+render = 'always'
+{{< /code-toggle >}}
+
+
+list
+: When to include the page within page collections. Specify one of:
+
+ - `always`
+ : Include the page in _all_ page collections. For example, `site.RegularPages`, `.Pages`, etc. This is the default value.
+
+ - `local`
+ : Include the page in _local_ page collections. For example, `.RegularPages`, `.Pages`, etc. Use this option to create fully navigable but headless content sections.
+
+ - `never`
+ : Do not include the page in _any_ page collection.
+
+publishResources
+: Applicable to [page bundles], determines whether to publish the associated [page resources]. Specify one of:
+
+ - `true`
+ : Always publish resources. This is the default value.
+
+ - `false`
+ : Only publish a resource when invoking its [`Permalink`], [`RelPermalink`], or [`Publish`] method within a template.
+
+render
+: When to render the page. Specify one of:
+
+ - `always`
+ : Always render the page to disk. This is the default value.
+
+ - `link`
- {{< code-toggle file=content/books/_index.md >}}
++ : Do not render the page to disk, but assign `Permalink` and `RelPermalink` values.
+
+ - `never`
+ : Never render the page to disk, and exclude it from all page collections.
+
+[page bundles]: content-management/page-bundles
+[page resources]: /content-management/page-resources
+[`Permalink`]: /methods/resource/permalink
+[`RelPermalink`]: /methods/resource/relpermalink
+[`Publish`]: /methods/resource/publish
+
+{{% note %}}
+Any page, regardless of its build options, will always be available by using the [`.Page.GetPage`] or [`.Site.GetPage`] method.
+
+[`.Page.GetPage`]: /methods/page/getpage
+[`.Site.GetPage`]: /methods/site/getpage
+{{% /note %}}
+
+## Example -- headless page
+
+Create a unpublished page whose content and resources can be included in other pages.
+
+```text
+content/
+├── headless/
+│ ├── a.jpg
+│ ├── b.jpg
+│ └── index.md <-- leaf bundle
+└── _index.md <-- home page
+```
+
+Set the build options in front matter:
+
+{{< code-toggle file=content/headless/index.md fm=true >}}
+title = 'Headless page'
+[_build]
+ list = 'never'
+ publishResources = false
+ render = 'never'
+{{< /code-toggle >}}
+
+To include the content and images on the home page:
+
+{{< code file=layouts/_default/home.html >}}
+{{ with .Site.GetPage "/headless" }}
+ {{ .Content }}
+ {{ range .Resources.ByType "image" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ end }}
+{{< /code >}}
+
+The published site will have this structure:
+
+```text
+public/
+├── headless/
+│ ├── a.jpg
+│ └── b.jpg
+└── index.html
+```
+
+In the example above, note that:
+
+1. Hugo did not publish an HTML file for the page.
+2. Despite setting `publishResources` to `false` in front matter, Hugo published the [page resources] because we invoked the [`RelPermalink`] method on each resource. This is the expected behavior.
+
+## Example -- headless section
+
+Create a unpublished section whose content and resources can be included in other pages.
+
+[branch bundle]: /content-management/page-bundles
+
+```text
+content/
+├── headless/
+│ ├── note-1/
+│ │ ├── a.jpg
+│ │ ├── b.jpg
+│ │ └── index.md <-- leaf bundle
+│ ├── note-2/
+│ │ ├── c.jpg
+│ │ ├── d.jpg
+│ │ └── index.md <-- leaf bundle
+│ └── _index.md <-- branch bundle
+└── _index.md <-- home page
+```
+
+Set the build options in front matter, using the `cascade` keyword to "cascade" the values down to descendant pages.
+
+{{< code-toggle file=content/headless/_index.md fm=true >}}
+title = 'Headless section'
+[[cascade]]
+[cascade._build]
+ list = 'local'
+ publishResources = false
+ render = 'never'
+{{< /code-toggle >}}
+
+In the front matter above, note that we have set `list` to `local` to include the descendant pages in local page collections.
+
+To include the content and images on the home page:
+
+{{< code file=layouts/_default/home.html >}}
+{{ with .Site.GetPage "/headless" }}
+ {{ range .Pages }}
+ {{ .Content }}
+ {{ range .Resources.ByType "image" }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+ {{ end }}
+{{ end }}
+{{< /code >}}
+
+The published site will have this structure:
+
+```text
+public/
+├── headless/
+│ ├── note-1/
+│ │ ├── a.jpg
+│ │ └── b.jpg
+│ └── note-2/
+│ ├── c.jpg
+│ └── d.jpg
+└── index.html
+```
+
+In the example above, note that:
+
+1. Hugo did not publish an HTML file for the page.
+2. Despite setting `publishResources` to `false` in front matter, Hugo correctly published the [page resources] because we invoked the [`RelPermalink`] method on each resource. This is the expected behavior.
+
+## Example -- list without publishing
+
+Publish a section page without publishing the descendant pages. For example, to create a glossary:
+
+```text
+content/
+├── glossary/
+│ ├── _index.md
+│ ├── bar.md
+│ ├── baz.md
+│ └── foo.md
+└── _index.md
+```
+
+Set the build options in front matter, using the `cascade` keyword to "cascade" the values down to descendant pages.
+
+{{< code-toggle file=content/glossary/_index.md fm=true >}}
+title = 'Glossary'
+[_build]
+render = 'always'
+[[cascade]]
+[cascade._build]
+ list = 'local'
+ publishResources = false
+ render = 'never'
+{{< /code-toggle >}}
+
+To render the glossary:
+
+{{< code file=layouts/glossary/list.html >}}
+<dl>
+ {{ range .Pages }}
+ <dt>{{ .Title }}</dt>
+ <dd>{{ .Content }}</dd>
+ {{ end }}
+</dl>
+{{< /code >}}
+
+The published site will have this structure:
+
+```text
+public/
+├── glossary/
+│ └── index.html
+└── index.html
+```
+
+## Example -- publish without listing
+
+Publish a section's descendant pages without publishing the section page itself.
+
+```text
+content/
+├── books/
+│ ├── _index.md
+│ ├── book-1.md
+│ └── book-2.md
+└── _index.md
+```
+
+Set the build options in front matter:
+
++{{< code-toggle file=content/books/_index.md fm=true >}}
+title = 'Books'
+[_build]
+render = 'never'
+list = 'never'
+{{< /code-toggle >}}
+
+The published site will have this structure:
+
+```html
+public/
+├── books/
+│ ├── book-1/
+│ │ └── index.html
+│ └── book-2/
+│ └── index.html
+└── index.html
+```
+
+## Example -- conditionally hide section
+
+Consider this example. A documentation site has a team of contributors with access to 20 custom shortcodes. Each shortcode takes several arguments, and requires documentation for the contributors to reference when using them.
+
+Instead of external documentation for the shortcodes, include an "internal" section that is hidden when building the production site.
+
+```text
+content/
+├── internal/
+│ ├── shortcodes/
+│ │ ├── _index.md
+│ │ ├── shortcode-1.md
+│ │ └── shortcode-2.md
+│ └── _index.md
+├── reference/
+│ ├── _index.md
+│ ├── reference-1.md
+│ └── reference-2.md
+├── tutorials/
+│ ├── _index.md
+│ ├── tutorial-1.md
+│ └── tutorial-2.md
+└── _index.md
+```
+
+Set the build options in front matter, using the `cascade` keyword to "cascade" the values down to descendant pages, and use the `target` keyword to target the production environment.
+
+{{< code-toggle file=content/internal/_index.md >}}
+title = 'Internal'
+[[cascade]]
+[cascade._build]
+render = 'never'
+list = 'never'
+[cascade._target]
+environment = 'production'
+{{< /code-toggle >}}
+
+The production site will have this structure:
+
+```html
+public/
+├── reference/
+│ ├── reference-1/
+│ │ └── index.html
+│ ├── reference-2/
+│ │ └── index.html
+│ └── index.html
+├── tutorials/
+│ ├── tutorial-1/
+│ │ └── index.html
+│ ├── tutorial-2/
+│ │ └── index.html
+│ └── index.html
+└── index.html
+```
--- /dev/null
- signatures: [cast/ToInt INPUT]
+---
+title: cast.ToInt
+description: Converts a value to a decimal integer (base 10).
+keywords: []
+action:
+ aliases: [int]
+ related:
+ - functions/cast/ToFloat
+ - functions/cast/ToString
+ returnType: int
- `{{ strings/TrimLeft "0" "0011" | int }} → 11`
++ signatures: [cast.ToInt INPUT]
+aliases: [/functions/int]
+---
+
+With a decimal (base 10) input:
+
+```go-html-template
+{{ int 11 }} → 11 (int)
+{{ int "11" }} → 11 (int)
+
+{{ int 11.1 }} → 11 (int)
+{{ int 11.9 }} → 11 (int)
+```
+
+With a binary (base 2) input:
+
+```go-html-template
+{{ int 0b11 }} → 3 (int)
+{{ int "0b11" }} → 3 (int)
+```
+
+With an octal (base 8) input (use either notation):
+
+```go-html-template
+{{ int 011 }} → 9 (int)
+{{ int "011" }} → 9 (int)
+
+{{ int 0o11 }} → 9 (int)
+{{ int "0o11" }} → 9 (int)
+```
+
+With a hexadecimal (base 16) input:
+
+```go-html-template
+{{ int 0x11 }} → 17 (int)
+{{ int "0x11" }} → 17 (int)
+```
+
+{{% note %}}
+Values with a leading zero are octal (base 8). When casting a string representation of a decimal (base 10) number, remove leading zeros:
+
++`{{ strings.TrimLeft "0" "0011" | int }} → 11`
+{{% /note %}}
--- /dev/null
+---
+title: crypto.FNV32a
+description: Returns the FNV (Fowler–Noll–Vo) 32-bit hash of a given string.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/crypto/HMAC
+ - functions/crypto/MD5
+ - functions/crypto/SHA1
+ - functions/crypto/SHA256
+ returnType: int
+ signatures: [crypto.FNV32a STRING]
+aliases: [/functions/crypto.fnv32a]
+---
+
++{{< new-in 0.98.0 >}}
++
+This function calculates the 32-bit [FNV1a hash](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash) of a given string according to the [specification](https://datatracker.ietf.org/doc/html/draft-eastlake-fnv-12):
+
+```go-html-template
+{{ crypto.FNV32a "Hello world" }} → 1498229191
+```
--- /dev/null
- The `lang.Translate` function returns the value associated with given key as defined in the translation table for the current language.
+---
+title: lang.Translate
+description: Translates a string using the translation tables in the i18n directory.
+categories: []
+keywords: []
+action:
+ aliases: [T, i18n]
+ related: []
+ returnType: string
+ signatures: ['lang.Translate KEY [CONTEXT]']
++toc: true
+aliases: [/functions/i18n]
+---
+
- If the key is not found in the translation table for the current language, the `lang.Translate` function falls back to the translation table for the [`defaultContentLanguage`].
-
- If the key is not found in the translation table for the `defaultContentLanguage`, the `lang.Translate` function returns an empty string.
++The `lang.Translate` function returns the value associated with given key as defined in the translation table for the current language.
+
- The translation tables can contain both:
++If the key is not found in the translation table for the current language, the `lang.Translate` function falls back to the translation table for the [`defaultContentLanguage`].
+
+[`defaultContentLanguage`]: /getting-started/configuration/#defaultcontentlanguage
+
++If the key is not found in the translation table for the `defaultContentLanguage`, the `lang.Translate` function returns an empty string.
++
+{{% note %}}
+To list missing and fallback translations, use the `--printI18nWarnings` flag when building your site.
+
+To render placeholders for missing and fallback translations, set
+[`enableMissingTranslationPlaceholders`] to `true` in your site configuration.
+
+[`enableMissingTranslationPlaceholders`]: /getting-started/configuration/#enablemissingtranslationplaceholders
+{{% /note %}}
+
++## Translation tables
++
++Create translation tables in the i18n directory, naming each file according to [RFC 5646]. Translation tables may be JSON, TOML, or YAML. For example:
++
++```text
++i18n/en.toml
++i18n/en-US.toml
++```
++
++The base name must match the language key as defined in your site configuration.
++
++Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7] are also supported. You may omit the `art-x-` prefix for brevity. For example:
++
++```text
++i18n/art-x-hugolang.toml
++i18n/hugolang.toml
++```
++
++Private use subtags must not exceed 8 alphanumeric characters.
++
++[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646
++[RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7
++
++## Simple translations
++
+Let's say your multilingual site supports two languages, English and Polish. Create a translation table for each language in the `i18n` directory.
+
+```text
+i18n/
+├── en.toml
+└── pl.toml
+```
+
- - Simple translations
- - Translations with pluralization
++The English translation table:
++
++{{< code-toggle file=i18n/en >}}
++privacy = 'privacy'
++security = 'security'
++{{< /code-toggle >}}
+
- privacy = 'privacy'
- security = 'security'
-
++The Polish translation table:
++
++{{< code-toggle file=i18n/pl >}}
++privacy = 'prywatność'
++security = 'bezpieczeństwo'
++{{< /code-toggle >}}
++
++{{% note %}}
++The examples below use the `T` alias for brevity.
++{{% /note %}}
++
++When viewing the English language site:
++
++```go-html-template
++{{ T "privacy" }} → privacy
++{{ T "security" }} → security
++````
++
++When viewing the Polish language site:
++
++```go-html-template
++{{ T "privacy" }} → prywatność
++{{ T "security" }} → bezpieczeństwo
++```
++
++## Translations with pluralization
++
++Let's say your multilingual site supports two languages, English and Polish. Create a translation table for each language in the `i18n` directory.
++
++```text
++i18n/
++├── en.toml
++└── pl.toml
++```
+
+The Unicode [CLDR Plural Rules chart] describes the pluralization categories for each language.
+
+[CLDR Plural Rules chart]: https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html
+
+The English translation table:
+
+{{< code-toggle file=i18n/en >}}
- privacy = 'prywatność'
- security = 'bezpieczeństwo'
-
+[day]
+one = 'day'
+other = 'days'
+
+[day_with_count]
+one = '{{ . }} day'
+other = '{{ . }} days'
+{{< /code-toggle >}}
+
+The Polish translation table:
+
+{{< code-toggle file=i18n/pl >}}
- {{ T "privacy" }} → privacy
- {{ T "security" }} → security
-
+[day]
+one = 'miesiąc'
+few = 'miesiące'
+many = 'miesięcy'
+other = 'miesiąca'
+
+[day_with_count]
+one = '{{ . }} miesiąc'
+few = '{{ . }} miesiące'
+many = '{{ . }} miesięcy'
+other = '{{ . }} miesiąca'
+{{< /code-toggle >}}
+
+{{% note %}}
+The examples below use the `T` alias for brevity.
+{{% /note %}}
+
+When viewing the English language site:
+
+```go-html-template
- {{ T "privacy" }} → prywatność
- {{ T "security" }} → bezpieczeństwo
-
+{{ T "day" 0 }} → days
+{{ T "day" 1 }} → day
+{{ T "day" 2 }} → days
+{{ T "day" 5 }} → days
+
+{{ T "day_with_count" 0 }} → 0 days
+{{ T "day_with_count" 1 }} → 1 day
+{{ T "day_with_count" 2 }} → 2 days
+{{ T "day_with_count" 5 }} → 5 days
+````
+
+When viewing the Polish language site:
+
+```go-html-template
+{{ T "day" 0 }} → miesięcy
+{{ T "day" 1 }} → miesiąc
+{{ T "day" 2 }} → miesiące
+{{ T "day" 5 }} → miesięcy
+
+{{ T "day_with_count" 0 }} → 0 miesięcy
+{{ T "day_with_count" 1 }} → 1 miesiąc
+{{ T "day_with_count" 2 }} → 2 miesiące
+{{ T "day_with_count" 5 }} → 5 miesięcy
+```
+
+In the pluralization examples above, we passed an integer in context (the second argument). You can also pass a map in context, providing a `count` key to control pluralization.
+
+Translation table:
+
+{{< code-toggle file=i18n/en >}}
+[age]
+one = '{{ .name }} is {{ .count }} year old.'
+other = '{{ .name }} is {{ .count }} years old.'
+{{< /code-toggle >}}
+
+Template code:
+
+```go-html-template
+{{ T "age" (dict "name" "Will" "count" 1) }} → Will is 1 year old.
+{{ T "age" (dict "name" "John" "count" 3) }} → John is 3 years old.
+```
++
++{{% note %}}
++Translation tables may contain both simple translations and translations with pluralization.
++{{% /note %}}
++
++## Reserved keys
++
++Hugo uses the [go-i18n] package to look up values in translation tables. This package reserves the following keys for internal use:
++
++[go-i18n]: https://github.com/nicksnyder/go-i18n
++
++id
++: (`string`) Uniquely identifies the message.
++
++description
++: (`string`) Describes the message to give additional context to translators that may be relevant for translation.
++
++hash
++: (`string`) Uniquely identifies the content of the message that this message was translated from.
++
++leftdelim
++: (`string`) The left Go template delimiter.
++
++rightdelim
++: (`string`) The right Go template delimiter.
++
++zero
++: (`string`) The content of the message for the [CLDR] plural form "zero".
++
++one
++: (`string`) The content of the message for the [CLDR] plural form "one".
++
++two
++: (`string`) The content of the message for the [CLDR] plural form "two".
++
++few
++: (`string`) The content of the message for the [CLDR] plural form "few".
++
++many
++: (`string`) The content of the message for the [CLDR] plural form "many".
++
++other
++: (`string`) The content of the message for the [CLDR] plural form "other".
++
++[CLDR]: https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html
++
++If you need to provide a translation for one of the reserved keys, you can prepend the word with an underscore. For example:
++
++{{< code-toggle file=i18n/es >}}
++_description = 'descripción'
++_few = 'pocos'
++_many = 'muchos'
++_one = 'uno'
++_other = 'otro'
++_two = 'dos'
++_zero = 'cero'
++{{< /code-toggle >}}
++
++Then in your templates:
++
++```go-html-template
++{{ T "_description" }} → descripción
++{{ T "_few" }} → pocos
++{{ T "_many" }} → muchos
++{{ T "_one" }} → uno
++{{ T "_two" }} → dos
++{{ T "_zero" }} → cero
++{{ T "_other" }} → otro
++```
--- /dev/null
- {{ $resource := resource.GetRemote $url (dict "key" $cacheKey) }}
+---
+title: resources.GetRemote
+description: Returns a remote resource from the given URL, or nil if none found.
+categories: []
+keywords: []
+action:
+ aliases: []
+ related:
+ - functions/data/GetCSV
+ - functions/data/GetJSON
+ - functions/resources/ByType
+ - functions/resources/Get
+ - functions/resources/GetMatch
+ - functions/resources/Match
+ - methods/page/Resources
+ returnType: resource.Resource
+ signatures: ['resources.GetRemote URL [OPTIONS]']
+toc: true
+---
+
+```go-html-template
+{{ $url := "https://example.org/images/a.jpg" }}
+{{ with resources.GetRemote $url }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+{{ end }}
+```
+
+## Options
+
+The `resources.GetRemote` function takes an optional map of options.
+
+```go-html-template
+{{ $url := "https://example.org/api" }}
+{{ $opts := dict
+ "headers" (dict "Authorization" "Bearer abcd")
+}}
+{{ $resource := resources.GetRemote $url $opts }}
+```
+
+If you need multiple values for the same header key, use a slice:
+
+```go-html-template
+{{ $url := "https://example.org/api" }}
+{{ $opts := dict
+ "headers" (dict "X-List" (slice "a" "b" "c"))
+}}
+{{ $resource := resources.GetRemote $url $opts }}
+```
+
+You can also change the request method and set the request body:
+
+```go-html-template
+{{ $url := "https://example.org/api" }}
+{{ $opts := dict
+ "method" "post"
+ "body" `{"complete": true}`
+ "headers" (dict "Content-Type" "application/json")
+}}
+{{ $resource := resources.GetRemote $url $opts }}
+```
+
+## Remote data
+
+When retrieving remote data, use the [`transform.Unmarshal`] function to [unmarshal] the response.
+
+[`transform.Unmarshal`]: /functions/transform/unmarshal
+[unmarshal]: /getting-started/glossary/#unmarshal
+
+```go-html-template
+{{ $data := "" }}
+{{ $url := "https://example.org/books.json" }}
+{{ with resources.GetRemote $url }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else }}
+ {{ $data = . | transform.Unmarshal }}
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+{{ end }}
+```
+
+## Error handling
+
+The [`Err`] method on a resource returned by the `resources.GetRemote` function returns an error message if the HTTP request fails, else nil. If you do not handle the error yourself, Hugo will fail the build.
+
+[`Err`]: /methods/resource/err
+
+```go-html-template
+{{ $url := "https://broken-example.org/images/a.jpg" }}
+{{ with resources.GetRemote $url }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+{{ end }}
+```
+
+To log an error as a warning instead of an error:
+
+```go-html-template
+{{ $url := "https://broken-example.org/images/a.jpg" }}
+{{ with resources.GetRemote $url }}
+ {{ with .Err }}
+ {{ warnf "%s" . }}
+ {{ else }}
+ <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+{{ end }}
+```
+
+## HTTP response
+
+The [`Data`] method on a resource returned by the `resources.GetRemote` function returns information from the HTTP response.
+
+[`Data`]: /methods/resource/data
+
+```go-html-template
+{{ $url := "https://example.org/images/a.jpg" }}
+{{ with resources.GetRemote $url }}
+ {{ with .Err }}
+ {{ errorf "%s" . }}
+ {{ else }}
+ {{ with .Data }}
+ {{ .ContentLength }} → 42764
+ {{ .ContentType }} → image/jpeg
+ {{ .Status }} → 200 OK
+ {{ .StatusCode }} → 200
+ {{ .TransferEncoding }} → []
+ {{ end }}
+ {{ end }}
+{{ else }}
+ {{ errorf "Unable to get remote resource %q" $url }}
+{{ end }}
+```
+
+ContentLength
+: (`int`) The content length in bytes.
+
+ContentType
+: (`string`) The content type.
+
+Status
+: (`string`) The HTTP status text.
+
+StatusCode
+: (`int`) The HTTP status code.
+
+TransferEncoding
+: (`string`) The transfer encoding.
+
+## Caching
+
+Resources returned from `resources.GetRemote` are cached to disk. See [configure file caches] for details.
+
+By default, Hugo derives the cache key from the arguments passed to the function, the URL and the options map, if any.
+
+Override the cache key by setting a `key` in the options map. Use this approach to have more control over how often Hugo fetches a remote resource.
+
+```go-html-template
+{{ $url := "https://example.org/images/a.jpg" }}
+{{ $cacheKey := print $url (now.Format "2006-01-02") }}
++{{ $resource := resources.GetRemote $url (dict "key" $cacheKey) }}
+```
+
+[configure file caches]: /getting-started/configuration/#configure-file-caches
+
+## Security
+
+To protect against malicious intent, the `resources.GetRemote` function inspects the server response including:
+
+- The [Content-Type] in the response header
+- The file extension, if any
+- The content itself
+
+If Hugo is unable to resolve the media type to an entry in its [allowlist], the function throws an error:
+
+```text
+ERROR error calling resources.GetRemote: failed to resolve media type...
+```
+
+For example, you will see the error above if you attempt to download an executable.
+
+Although the allowlist contains entries for common media types, you may encounter situations where Hugo is unable to resolve the media type of a file that you know to be safe. In these situations, edit your site configuration to add the media type to the allowlist. For example:
+
+```text
+[security.http]
+mediaTypes=['application/vnd\.api\+json']
+```
+
+Note that the entry above is:
+
+- An _addition_ to the allowlist; it does not _replace_ the allowlist
+- An array of regular expressions
+
+For example, to add two entries to the allowlist:
+
+```text
+[security.http]
+mediaTypes=['application/vnd\.api\+json','image/avif']
+```
+
+[allowlist]: https://en.wikipedia.org/wiki/Whitelist
+[Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
--- /dev/null
- <div>Short Description of {{ .Site.Data.User0123.Name }}: <p>{{ index .Site.Data.User0123 "Short Description" | markdownify }}</p></div>
+---
+title: Data templates
+description: In addition to Hugo's built-in variables, you can specify your own custom data in templates or shortcodes that pull from both local and dynamic sources.
+categories: [templates]
+keywords: [data,dynamic,csv,json,toml,yaml,xml]
+menu:
+ docs:
+ parent: templates
+ weight: 150
+weight: 150
+toc: true
+aliases: [/extras/datafiles/,/extras/datadrivencontent/,/doc/datafiles/]
+---
+
+Hugo supports loading data from YAML, JSON, XML, and TOML files located in the `data` directory at the root of your Hugo project.
+
+{{< youtube FyPgSuwIMWQ >}}
+
+## The data directory
+
+The `data` directory should store additional data for Hugo to use when generating your site.
+
+Data files are not for generating standalone pages. They should supplement content files by:
+
+- Extending the content when the front matter fields grow out of control, or
+- Showing a larger dataset in a template (see the example below).
+
+In both cases, it's a good idea to outsource the data in their (own) files.
+
+These files must be YAML, JSON, XML, or TOML files (using the `.yml`, `.yaml`, `.json`, `.xml`, or `.toml` extension). The data will be accessible as a `map` in the `.Site.Data` variable.
+
+To access the data using the `site.Data.filename` notation, the file name must begin with an underscore or a Unicode letter, followed by zero or more underscores, Unicode letters, or Unicode digits. For example:
+
+- `123.json` - Invalid
+- `x123.json` - Valid
+- `_123.json` - Valid
+
+To access the data using the [`index`](/functions/collections/indexfunction) function, the file name is irrelevant. For example:
+
+Data file|Template code
+:--|:--
+`123.json`|`{{ index .Site.Data "123" }}`
+`x123.json`|`{{ index .Site.Data "x123" }}`
+`_123.json`|`{{ index .Site.Data "_123" }}`
+`x-123.json`|`{{ index .Site.Data "x-123" }}`
+
+## Data files in themes
+
+Data Files can also be used in themes.
+
+However, note that the theme data files are merged with the project directory taking precedence. That is, Given two files with the same name and relative path, the data in the file in the root project `data` directory will override the data from the file in the `themes/<THEME>/data` directory *for keys that are duplicated*).
+
+Therefore, theme authors should be careful not to include data files that could be easily overwritten by a user who decides to [customize a theme][customize]. For theme-specific data items that shouldn't be overridden, it can be wise to prefix the folder structure with a namespace; e.g. `mytheme/data/<THEME>/somekey/...`. To check if any such duplicate exists, run hugo with the `-v` flag.
+
+The keys in the map created with data templates from data files will be a dot-chained set of `path`, `filename`, and `key` in the file (if applicable).
+
+This is best explained with an example:
+
+## Examples
+
+### Jaco Pastorius' Solo Discography
+
+[Jaco Pastorius](https://en.wikipedia.org/wiki/Jaco_Pastorius_discography) was a great bass player, but his solo discography is short enough to use as an example. [John Patitucci](https://en.wikipedia.org/wiki/John_Patitucci) is another bass giant.
+
+The example below is a bit contrived, but it illustrates the flexibility of data Files. This example uses TOML as its file format with the two following data files:
+
+* `data/jazz/bass/jacopastorius.toml`
+* `data/jazz/bass/johnpatitucci.toml`
+
+`jacopastorius.toml` contains the content below. `johnpatitucci.toml` contains a similar list:
+
+{{< code-toggle file=data/jazz/bass/jacopastorius >}}
+discography = [
+"1974 - Modern American Music … Period! The Criteria Sessions",
+"1974 - Jaco",
+"1976 - Jaco Pastorius",
+"1981 - Word of Mouth",
+"1981 - The Birthday Concert (released in 1995)",
+"1982 - Twins I & II (released in 1999)",
+"1983 - Invitation",
+"1986 - Broadway Blues (released in 1998)",
+"1986 - Honestly Solo Live (released in 1990)",
+"1986 - Live In Italy (released in 1991)",
+"1986 - Heavy'n Jazz (released in 1992)",
+"1991 - Live In New York City, Volumes 1-7.",
+"1999 - Rare Collection (compilation)",
+"2003 - Punk Jazz: The Jaco Pastorius Anthology (compilation)",
+"2007 - The Essential Jaco Pastorius (compilation)"
+]
+{{< /code-toggle >}}
+
+The list of bass players can be accessed via `.Site.Data.jazz.bass`, a single bass player by adding the file name without the suffix, e.g. `.Site.Data.jazz.bass.jacopastorius`.
+
+You can now render the list of recordings for all the bass players in a template:
+
+```go-html-template
+{{ range $.Site.Data.jazz.bass }}
+ {{ partial "artist.html" . }}
+{{ end }}
+```
+
+And then in the `partials/artist.html`:
+
+```go-html-template
+<ul>
+{{ range .discography }}
+ <li>{{ . }}</li>
+{{ end }}
+</ul>
+```
+
+Discover a new favorite bass player? Just add another `.toml` file in the same directory.
+
+### Accessing named values in a data file
+
+Assume you have the following data structure in your `user0123` data file located directly in `data/`:
+
+{{< code-toggle file=data/user0123 >}}
+Name: User0123
+"Short Description": "He is a **jolly good** fellow."
+Achievements:
+ - "Can create a Key, Value list from Data File"
+ - "Learns Hugo"
+ - "Reads documentation"
+{{</ code-toggle >}}
+
+You can use the following code to render the `Short Description` in your layout:
+
+```go-html-template
++<div>Short Description of {{ .Site.Data.user0123.Name }}: <p>{{ index .Site.Data.user0123 "Short Description" | markdownify }}</p></div>
+```
+
+Note the use of the [`markdownify`] function. This will send the description through the Markdown rendering engine.
+
+## Remote data
+
+Retrieve remote data using these template functions:
+
+- [`resources.GetRemote`](/functions/resources/getremote) (recommended)
+- [`data.GetCSV`](/functions/data/getcsv)
+- [`data.GetJSON`](/functions/data/getjson)
+
+## LiveReload with data files
+
+There is no chance to trigger a [LiveReload] when the content of a URL changes. However, when a *local* file changes (i.e., `data/*` and `themes/<THEME>/data/*`), a LiveReload will be triggered. Symlinks are not supported. Note too that because downloading data takes a while, Hugo stops processing your Markdown files until the data download has been completed.
+
+{{% note %}}
+If you change any local file and the LiveReload is triggered, Hugo will read the data-driven (URL) content from the cache. If you have disabled the cache (i.e., by running the server with `hugo server --ignoreCache`), Hugo will re-download the content every time LiveReload triggers. This can create *huge* traffic. You may reach API limits quickly.
+{{% /note %}}
+
+## Examples of data-driven content
+
+- Photo gallery JSON powered: [https://github.com/pcdummy/hugo-lightslider-example](https://github.com/pcdummy/hugo-lightslider-example)
+- GitHub Starred Repositories [in a post](https://github.com/SchumacherFM/blog-cs/blob/master/content%2Fposts%2Fgithub-starred.md) using data-driven content in a [custom short code](https://github.com/SchumacherFM/blog-cs/blob/master/layouts%2Fshortcodes%2FghStarred.html).
+
+## Specs for data formats
+
+* [TOML Spec][toml]
+* [YAML Spec][yaml]
+* [JSON Spec][json]
+* [CSV Spec][csv]
+* [XML Spec][xml]
+
+[config]: /getting-started/configuration/
+[csv]: https://tools.ietf.org/html/rfc4180
+[customize]: /hugo-modules/theme-components/
+[json]: https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
+[LiveReload]: /getting-started/usage/#livereload
+[lookup]: /templates/lookup-order/
+[`markdownify`]: /functions/transform/markdownify
+[OAuth]: https://en.wikipedia.org/wiki/OAuth
+[partials]: /templates/partials/
+[toml]: https://toml.io/en/latest
+[variadic]: https://en.wikipedia.org/wiki/Variadic_function
+[vars]: /variables/
+[yaml]: https://yaml.org/spec/
+[xml]: https://www.w3.org/XML/
--- /dev/null
- `.Paginator` is provided to help you build a pager menu. This feature is currently only supported on homepage and list pages (i.e., taxonomies and section lists).
+---
+title: Pagination
+description: Hugo supports pagination for your homepage, section pages, and taxonomies.
+categories: [templates]
+keywords: [lists,sections,pagination]
+menu:
+ docs:
+ parent: templates
+ weight: 100
+weight: 100
+toc: true
+aliases: [/extras/pagination,/doc/pagination/]
+---
+
+The real power of Hugo pagination shines when combined with the [`where`] function and its SQL-like operators: [`first`], [`last`], and [`after`]. You can even [order the content][lists] the way you've become used to with Hugo.
+
+## Configure pagination
+
+Pagination can be configured in your [site configuration][configuration]:
+
+paginate
+: default = `10`. This setting can be overridden within the template.
+
+paginatePath
+: default = `page`. Allows you to set a different path for your pagination pages.
+
+Setting `paginate` to a positive value will split the list pages for the homepage, sections and taxonomies into chunks of that size. But note that the generation of the pagination pages for sections, taxonomies and homepage is *lazy* --- the pages will not be created if not referenced by a `.Paginator` (see below).
+
+`paginatePath` is used to adapt the `URL` to the pages in the paginator (the default setting will produce URLs on the form `/page/1/`.
+
+## List paginator pages
+
+{{% note %}}
++Paginate a page collection in list templates for these page kinds: `home`, `section`, `taxonomy`, or `term`. You cannot paginate a page collection in a template for the `page` page kind.
+{{% /note %}}
+
+There are two ways to configure and use a `.Paginator`:
+
+1. The simplest way is just to call `.Paginator.Pages` from a template. It will contain the pages for *that page*.
+2. Select another set of pages with the available template functions and ordering options, and pass the slice to `.Paginate`, e.g.
+ * `{{ range (.Paginate ( first 50 .Pages.ByTitle )).Pages }}` or
+ * `{{ range (.Paginate .RegularPagesRecursive).Pages }}`.
+
+For a given **Page**, it's one of the options above. The `.Paginator` is static and cannot change once created.
+
+If you call `.Paginator` or `.Paginate` multiple times on the same page, you should ensure all the calls are identical. Once *either* `.Paginator` or `.Paginate` is called while generating a page, its result is cached, and any subsequent similar call will reuse the cached result. This means that any such calls which do not match the first one will not behave as written.
+
+(Remember that function arguments are eagerly evaluated, so a call like `$paginator := cond x .Paginator (.Paginate .RegularPagesRecursive)` is an example of what you should *not* do. Use `if`/`else` instead to ensure exactly one evaluation.)
+
+The global page size setting (`Paginate`) can be overridden by providing a positive integer as the last argument. The examples below will give five items per page:
+
+* `{{ range (.Paginator 5).Pages }}`
+* `{{ $paginator := .Paginate (where .Pages "Type" "posts") 5 }}`
+
+It is also possible to use the `GroupBy` functions in combination with pagination:
+
+```go-html-template
+{{ range (.Paginate (.Pages.GroupByDate "2006")).PageGroups }}
+```
+
+## Build the navigation
+
+The `.Paginator` contains enough information to build a paginator interface.
+
+The easiest way to add this to your pages is to include the built-in template (with `Bootstrap`-compatible styles):
+
+```go-html-template
+{{ template "_internal/pagination.html" . }}
+```
+
+{{% note %}}
+If you use any filters or ordering functions to create your `.Paginator` *and* you want the navigation buttons to be shown before the page listing, you must create the `.Paginator` before it's used.
+{{% /note %}}
+
+The following example shows how to create `.Paginator` before its used:
+
+```go-html-template
+{{ $paginator := .Paginate (where .Pages "Type" "posts") }}
+{{ template "_internal/pagination.html" . }}
+{{ range $paginator.Pages }}
+ {{ .Title }}
+{{ end }}
+```
+
+Without the `where` filter, the above example is even simpler:
+
+```go-html-template
+{{ template "_internal/pagination.html" . }}
+{{ range .Paginator.Pages }}
+ {{ .Title }}
+{{ end }}
+```
+
+If you want to build custom navigation, you can do so using the `.Paginator` object, which includes the following properties:
+
+PageNumber
+: The current page's number in the pager sequence
+
+URL
+: The relative URL to the current pager
+
+Pages
+: The pages in the current pager
+
+NumberOfElements
+: The number of elements on this page
+
+HasPrev
+: Whether there are page(s) before the current
+
+Prev
+: The pager for the previous page
+
+HasNext
+: Whether there are page(s) after the current
+
+Next
+: The pager for the next page
+
+First
+: The pager for the first page
+
+Last
+: The pager for the last page
+
+Pagers
+: A list of pagers that can be used to build a pagination menu
+
+PageSize
+: Size of each pager
+
+TotalPages
+: The number of pages in the paginator
+
+TotalNumberOfElements
+: The number of elements on all pages in this paginator
+
+## Additional information
+
+The pages are built on the following form (`BLANK` means no value):
+
+```txt
+[SECTION/TAXONOMY/BLANK]/index.html
+[SECTION/TAXONOMY/BLANK]/page/1/index.html => redirect to [SECTION/TAXONOMY/BLANK]/index.html
+[SECTION/TAXONOMY/BLANK]/page/2/index.html
+....
+```
+
+[`first`]: /functions/collections/first/
+[`last`]: /functions/collections/last/
+[`after`]: /functions/collections/after/
+[configuration]: /getting-started/configuration/
+[lists]: /templates/lists/
+[`where`]: /functions/collections/where
--- /dev/null
- 1. `layouts/partials/*<PARTIALNAME>.html`
- 2. `themes/<THEME>/layouts/partials/*<PARTIALNAME>.html`
+---
+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: [templates]
+keywords: [lists,sections,partials]
+menu:
+ docs:
+ parent: templates
+ weight: 120
+weight: 120
+toc: true
+aliases: [/templates/partial/,/layout/chrome/,/extras/analytics/]
+---
+
+{{< youtube pjS4pOLyB7c >}}
+
+## Partial template lookup order
+
+Partial templates---like [single page templates][singletemps] and [list page templates][listtemps]---have a specific [lookup order]. However, partials are simpler in that Hugo will only check in two places:
+
++1. `layouts/partials/<PARTIALNAME>.html`
++2. `themes/<THEME>/layouts/partials/<PARTIALNAME>.html`
+
+This allows a theme's end user to copy a partial's contents into a file of the same name for [further customization][customize].
+
+## 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
+ │ └── twitter.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/).
+{{% /note %}}
+
+{{% note %}}
+`<PARTIAL>` including `baseof` is reserved. ([#5373](https://github.com/gohugoio/hugo/issues/5373))
+{{% /note %}}
+
+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 `.`, 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 *has no access to 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.
+{{% /note %}}
+
+## 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/):
+
+{{< code 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>
+{{< /code >}}
+
+{{% 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.
+{{% /note %}}
+
+### `footer.html`
+
+The following `footer.html` partial template is used for [spf13.com](https://spf13.com/):
+
+{{< code 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>
+{{< /code >}}
+
+[context]: /templates/introduction/
+[customize]: /hugo-modules/theme-components/
+[listtemps]: /templates/lists/
+[lookup order]: /templates/lookup-order/
+[partialcached]: /functions/partials/includecached
+[singletemps]: /templates/single-page-templates/
+[themes]: /themes/