From: Bjørn Erik Pedersen Date: Sun, 1 Sep 2024 12:51:15 +0000 (+0200) Subject: Merge commit 'dec8cd4ada29218971743333f8ac662a9c06aad8' X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=0c453420e6fceccf36d06cea0a9e53ac6b8401ba;p=brevno-suite%2Fhugo Merge commit 'dec8cd4ada29218971743333f8ac662a9c06aad8' --- 0c453420e6fceccf36d06cea0a9e53ac6b8401ba diff --cc docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/_default/documentation-home.html index 91f744c30,000000000..f3cf291be mode 100644,000000..100644 --- a/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/_default/documentation-home.html +++ b/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/_default/documentation-home.html @@@ -1,4 -1,0 +1,4 @@@ +{{ define "main" }} - {{ $section_to_display := (.Site.Taxonomies.categories.fundamentals).Pages | lang.Merge (.Sites.First.Taxonomies.categories.fundamentals).Pages }} ++{{ $section_to_display := (.Site.Taxonomies.categories.fundamentals).Pages | lang.Merge (.Sites.Default.Taxonomies.categories.fundamentals).Pages }} + {{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }} +{{ end }} diff --cc docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/_default/list.html index 3b7a2307e,000000000..94057aafe mode 100644,000000..100644 --- a/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/_default/list.html +++ b/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/_default/list.html @@@ -1,5 -1,0 +1,5 @@@ +{{ define "main" }} - {{ $paginator := .Paginate (.Pages | lang.Merge (where .Sites.First.RegularPages "Section" .Section)) }} ++ {{ $paginator := .Paginate (.Pages | lang.Merge (where .Sites.Default.RegularPages "Section" .Section)) }} + {{ $section_to_display := .Sections | default $paginator.Pages }} + {{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }} +{{ end }} diff --cc docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/gomodules-info.html index b56758ac3,000000000..31d860394 mode 100644,000000..100644 --- a/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/gomodules-info.html +++ b/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/gomodules-info.html @@@ -1,17 -1,0 +1,18 @@@ +{{ $text := ` - Most of the commands for **Hugo Modules** require a newer version of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ). If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.12 in your Environment settings. ++Most of the commands for **Hugo Modules** require a newer version (>= 1.18) of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ). ++If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.19 or newer in your Environment settings. + +For more information about Go Modules, see: + +* https://github.com/golang/go/wiki/Modules +* https://blog.golang.org/using-go-modules +` }} + + diff --cc docs/_vendor/modules.txt index 1bde873a0,000000000..492b3e6ac mode 100644,000000..100644 --- a/docs/_vendor/modules.txt +++ b/docs/_vendor/modules.txt @@@ -1,1 -1,0 +1,1 @@@ - # github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472 ++# github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f diff --cc docs/content/en/about/features.md index cb710aa4b,000000000..835384723 mode 100644,000000..100644 --- a/docs/content/en/about/features.md +++ b/docs/content/en/about/features.md @@@ -1,139 -1,0 +1,139 @@@ +--- +title: Features +description: Hugo's rich and powerful feature set provides the framework and tools to create static sites that build in seconds, often less. +categories: [about] +keywords: [] +menu: + docs: + parent: about + weight: 30 +weight: 30 +toc: true +--- + +## Framework + +[Multiplatform] +: Install Hugo's single executable on Linux, macOS, Windows, and more. + +[Multilingual] +: Localize your project for each language and region, including translations, images, dates, currencies, numbers, percentages, and collation sequence. Hugo's multilingual framework supports single-host and multihost configurations. + +[Output formats] +: Render each page of your site to one or more output formats, with granular control by page kind, section, and path. While HTML is the default output format, you can add JSON, RSS, CSV, and more. For example, create a REST API to access content. + +[Templates] +: Create templates using variables, functions, and methods to transform your content, resources, and data into a published page. While HTML templates are the most common, you can create templates for any output format. + +[Themes] +: Reduce development time and cost by using one of the hundreds of themes contributed by the Hugo community. Themes are available for corporate sites, documentation projects, image portfolios, landing pages, personal and professional blogs, resumes, CVs, and more. + +[Modules] +: Reduce development time and cost by creating or importing packaged combinations of archetypes, assets, content, data, templates, translation tables, static files, or configuration settings. A module may serve as the basis for a new site, or to augment an existing site. + +[Privacy] +: Configure the behavior of Hugo's embedded templates and shortcodes to facilitate compliance with regional privacy regulations, including the [GDPR] and [CCPA]. + +[Security] +: Hugo's security model is based on the premise that template and configuration authors are trusted, but content authors are not. This model enables generation of HTML output safe against code injection. Other protections prevent "shelling out" to arbitrary applications, limit access to specific environment variables, prevent connections to arbitrary remote data sources, and more. + +## Content authoring + +[Content formats] +: Create your content using Markdown, HTML, AsciiDoc, Emacs Org Mode, Pandoc, or reStructuredText. Markdown is the default content format, conforming to the [CommonMark] and [GitHub Flavored Markdown] specifications. + +[Markdown attributes] +: Apply HTML attributes such as `class` and `id` to Markdown images and block elements including blockquotes, fenced code blocks, headings, horizontal rules, lists, paragraphs, and tables. + +[Markdown extensions] +: Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more. + +[Markdown render hooks] - : Override the conversion of Markdown to HTML when rendering fenced code blocks, headings, images, and links. For example, render every standalone image as an HTML `figure` element. ++: Override the conversion of Markdown to HTML when rendering blockquotes, fenced code blocks, headings, images, and links. For example, render every standalone image as an HTML `figure` element. + +[Diagrams] +: Use fenced code blocks and Markdown render hooks to include diagrams in your content. + +[Mathematics] +: Include mathematical equations and expressions in Markdown using LaTeX or TeX typesetting syntax. + +[Syntax highlighting] +: Syntactically highlight code examples using Hugo's embedded syntax highlighter, enabled by default for fenced code blocks in Markdown. The syntax highlighter supports hundreds of code languages and dozens of styles. + +[Shortcodes] +: Use Hugo's embedded shortcodes, or create your own, to insert complex content. For example, use shortcodes to include `audio` and `video` elements, render tables from local or remote data sources, insert snippets from other pages, and more. + +## Content management + +[Content adapters] +: Create content adapters to dynamically add content when building your site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML. + +[Taxonomies] +: Classify content to establish simple or complex logical relationships between pages. For example, create an authors taxonomy, and assign one or more authors to each page. Among other uses, the taxonomy system provides an inverted, weighted index to render a list of related pages, ordered by relevance. + +[Data] +: Augment your content using local or remote data sources including CSV, JSON, TOML, YAML, and XML. For example, create a shortcode to render an HTML table from a remote CSV file. + +[Menus] +: Provide rapid access to content via Hugo's menu system, configured automatically, globally, or on a page-by-page basis. The menu system is a key component of Hugo's multilingual architecture. + +[URL management] +: Serve any page from any path via global configuration or on a page-by-page basis. + +## Asset pipelines + +[Image processing] +: Convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data. + +[JavaScript bundling] +: Transpile TypeScript and JSX to JavaScript, bundle, tree shake, minify, create source maps, and perform SRI hashing. + +[Sass processing] +: Transpile Sass to CSS, bundle, tree shake, minify, create source maps, perform SRI hashing, and integrate with PostCSS. + +[Tailwind CSS processing] +: Compile Tailwind CSS utility classes into standard CSS, bundle, tree shake, optimize, minify, perform SRI hashing, and integrate with PostCSS. + +## Performance + +[Caching] +: Reduce build time and cost by rendering a partial template once then cache the result, either globally or within a given context. For example, cache the result of an asset pipeline to prevent reprocessing on every rendered page. + +[Segmentation] +: Reduce build time and cost by partitioning your sites into segments. For example, render the home page and the "news section" every hour, and render the entire site once a week. + +[Minification] +: Minify HTML, CSS, and JavaScript to reduce file size, bandwidth consumption, and loading times. + +[CCPA]: https://en.wikipedia.org/wiki/California_Consumer_Privacy_Act +[Sass processing]: /functions/css/Sass/ +[Caching]: /functions/partials/includecached/ +[CommonMark]: https://spec.commonmark.org/current/ +[Content adapters]: /content-management/content-adapters/ +[Content formats]: /content-management/formats/ +[Data]: /content-management/data-sources/ +[Diagrams]: /content-management/diagrams/ +[GDPR]: https://en.wikipedia.org/wiki/General_Data_Protection_Regulation +[GitHub Flavored Markdown]: https://github.github.com/gfm/ +[Image processing]: /content-management/image-processing/ +[JavaScript bundling]: /functions/js/build/ +[Markdown attributes]: /content-management/markdown-attributes/ +[Markdown extensions]: /getting-started/configuration-markup/#goldmark-extensions +[Markdown render hooks]: /render-hooks/introduction/ +[Mathematics]: /content-management/mathematics/ +[Menus]: /content-management/menus/ +[Minification]: /getting-started/configuration/#configure-minify +[Modules]: https://gohugo.io/hugo-modules/ +[Multilingual]: /content-management/multilingual/ +[Multiplatform]: /installation/ +[Output formats]: /templates/output-formats/ +[Privacy]: /about/privacy/ +[Security]: /about/security/ +[Segmentation]: /getting-started/configuration/#configure-segments +[Shortcodes]: /content-management/shortcodes/ +[Syntax highlighting]: /content-management/syntax-highlighting/ +[Tailwind CSS processing]: /functions/css/tailwindcss/ +[Taxonomies]: /content-management/taxonomies/ +[Templates]: templates/introduction/ +[Themes]: https://themes.gohugo.io/ +[URL management]: /content-management/urls/ diff --cc docs/content/en/content-management/content-adapters.md index ea5ec62ca,000000000..4d5bd0890 mode 100644,000000..100644 --- a/docs/content/en/content-management/content-adapters.md +++ b/docs/content/en/content-management/content-adapters.md @@@ -1,355 -1,0 +1,355 @@@ +--- +title: Content adapters +description: Create content adapters to dynamically add content when building your site. +categories: [content management] +keywords: [] +menu: + docs: + parent: content-management + weight: 290 +weight: 290 +toc: true +--- + +{{< new-in 0.126.0 >}} + +## Overview + +A content adapter is a template that dynamically creates pages when building a site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML. + +Unlike templates that reside in the layouts directory, content adapters reside in the content directory, no more than one per directory per language. When a content adapter creates a page, the page's [logical path] will be relative to the content adapter. + +```text +content/ +├── articles/ +│ ├── _index.md +│ ├── article-1.md +│ └── article-2.md +├── books/ +│ ├── _content.gotmpl <-- content adapter +│ └── _index.md +└── films/ + ├── _content.gotmpl <-- content adapter + └── _index.md +``` + +Each content adapter is named _content.gotmpl and uses the same [syntax] as templates in the layouts directory. You can use any of the [template functions] within a content adapter, as well as the methods described below. + +## Methods + +Use these methods within a content adapter. + +###### AddPage + +Adds a page to the site. + +{{< code file=content/books/_content.gotmpl >}} +{{ $content := dict + "mediaType" "text/markdown" + "value" "The _Hunchback of Notre Dame_ was written by Victor Hugo." +}} +{{ $page := dict + "content" $content + "kind" "page" + "path" "the-hunchback-of-notre-dame" + "title" "The Hunchback of Notre Dame" +}} +{{ .AddPage $page }} +{{< /code >}} + +###### AddResource + +Adds a page resource to the site. + +{{< code file=content/books/_content.gotmpl >}} +{{ with resources.Get "images/a.jpg" }} + {{ $content := dict + "mediaType" .MediaType.Type + "value" . + }} + {{ $resource := dict + "content" $content + "path" "the-hunchback-of-notre-dame/cover.jpg" + }} + {{ $.AddResource $resource }} +{{ end }} +{{< /code >}} + +Then retrieve the new page resource with something like: + +{{< code file=layouts/_default/single.html >}} +{{ with .Resources.Get "cover.jpg" }} + +{{ end }} +{{< /code >}} + +###### Site + +Returns the `Site` to which the pages will be added. + +{{< code file=content/books/_content.gotmpl >}} +{{ .Site.Title }} +{{< /code >}} + +###### Store + +Returns a persistent “scratch pad” to store and manipulate data. The main use case for this is to transfer values between executions when [EnableAllLanguages](#enablealllanguages) is set. See [examples](/methods/page/store/). + +{{< code file=content/books/_content.gotmpl >}} +{{ .Store.Set "key" "value" }} +{{ .Store.Get "key" }} +{{< /code >}} + +###### EnableAllLanguages + +By default, Hugo executes the content adapter for the language defined by the _content.gotmpl file . Use this method to activate the content adapter for all languages. + +{{< code file=content/books/_content.gotmpl >}} +{{ .EnableAllLanguages }} +{{ $content := dict + "mediaType" "text/markdown" + "value" "The _Hunchback of Notre Dame_ was written by Victor Hugo." +}} +{{ $page := dict + "content" $content + "kind" "page" + "path" "the-hunchback-of-notre-dame" + "title" "The Hunchback of Notre Dame" +}} +{{ .AddPage $page }} +{{< /code >}} + +## Page map + +Set any [front matter field] in the map passed to the [`AddPage`](#addpage) method, excluding `markup`. Instead of setting the `markup` field, specify the `content.mediaType` as described below. + +This table describes the fields most commonly passed to the `AddPage` method. + - Key|Descripion|Required ++Key|Description|Required +:--|:--|:-: +`content.mediaType`|The content [media type]. Default is `text/markdown`. See [content formats] for examples.|  +`content.value`|The content value as a string.|  +`dates.date`|The page creation date as a `time.Time` value.|  +`dates.expiryDate`|The page expiry date as a `time.Time` value.|  +`dates.lastmod`|The page last modification date as a `time.Time` value.|  +`dates.publishDate`|The page publication date as a `time.Time` value.|  +`kind`|The [page kind]. Default is `page`.|  +`params`|A map of page parameters.|  +`path`|The page's [logical path] relative to the content adapter. Do not include a leading slash or file extension.|:heavy_check_mark: +`title`|The page title.|  + +{{% note %}} +While `path` is the only required field, we recommend setting `title` as well. + +When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C` produces a logical path of `/section/a-b-c`. +{{% /note %}} + +## Resource map + +Construct the map passed to the [`AddResource`](#addresource) method using the fields below. + - Key|Descripion|Required ++Key|Description|Required +:--|:--|:-: +`content.mediaType`|The content [media type].|:heavy_check_mark: +`content.value`|The content value as a string or resource.|:heavy_check_mark: +`name`|The resource name.|  +`params`|A map of resource parameters.|  +`path`|The resources's [logical path] relative to the content adapter. Do not include a leading slash.|:heavy_check_mark: +`title`|The resource title.|  + +{{% note %}} +If the `content.value` is a string Hugo creates a new resource. If the `content.value` is a resource, Hugo obtains the value from the existing resource. + +When setting the `path`, Hugo transforms the given string to a logical path. For example, setting `path` to `A B C/cover.jpg` produces a logical path of `/section/a-b-c/cover.jpg`. +{{% /note %}} + +## Example + +Create pages from remote data, where each page represents a book review. + +Step 1 +: Create the content structure. + +```text +content/ +└── books/ + ├── _content.gotmpl <-- content adapter + └── _index.md +``` + +Step 2 +: Inspect the remote data to determine how to map key-value pairs to front matter fields. + +: + +Step 3 +: Create the content adapter. + +{{< code file=content/books/_content.gotmpl copy=true >}} +{{/* Get remote data. */}} +{{ $data := dict }} +{{ $url := "https://gohugo.io/shared/examples/data/books.json" }} +{{ with resources.GetRemote $url }} + {{ with .Err }} + {{ errorf "Unable to get remote resource %s: %s" $url . }} + {{ else }} + {{ $data = . | transform.Unmarshal }} + {{ end }} +{{ else }} + {{ errorf "Unable to get remote resource %s" $url }} +{{ end }} + +{{/* Add pages and page resources. */}} +{{ range $data }} + + {{/* Add page. */}} + {{ $content := dict "mediaType" "text/markdown" "value" .summary }} + {{ $dates := dict "date" (time.AsTime .date) }} + {{ $params := dict "author" .author "isbn" .isbn "rating" .rating "tags" .tags }} + {{ $page := dict + "content" $content + "dates" $dates + "kind" "page" + "params" $params + "path" .title + "title" .title + }} + {{ $.AddPage $page }} + + {{/* Add page resource. */}} + {{ $item := . }} + {{ with $url := $item.cover }} + {{ with resources.GetRemote $url }} + {{ with .Err }} + {{ errorf "Unable to get remote resource %s: %s" $url . }} + {{ else }} + {{ $content := dict "mediaType" .MediaType.Type "value" .Content }} + {{ $params := dict "alt" $item.title }} + {{ $resource := dict + "content" $content + "params" $params + "path" (printf "%s/cover.%s" $item.title .MediaType.SubType) + }} + {{ $.AddResource $resource }} + {{ end }} + {{ else }} + {{ errorf "Unable to get remote resource %s" $url }} + {{ end }} + {{ end }} + +{{ end }} +{{< /code >}} + +Step 4 +: Create a single template to render each book review. + +{{< code file=layouts/books/single.html copy=true >}} +{{ define "main" }} +

{{ .Title }}

+ + {{ with .Resources.GetMatch "cover.*" }} + {{ .Params.alt }} + {{ end }} + +

Author: {{ .Params.author }}

+ +

+ ISBN: {{ .Params.isbn }}
+ Rating: {{ .Params.rating }}
+ Review date: {{ .Date | time.Format ":date_long" }} +

+ + {{ with .GetTerms "tags" }} +

Tags:

+ + {{ end }} + + {{ .Content }} +{{ end }} +{{< /code >}} + +## Multilingual sites + +With multilingual sites you can: + +1. Create one content adapter for all languages using the [`EnableAllLanguages`](#enablealllanguages) method as described above. +2. Create content adapters unique to each language. See the examples below. + +### Translations by file name + +With this site configuration: + +{{< code-toggle file=hugo >}} +[languages.en] +weight = 1 + +[languages.de] +weight = 2 +{{< /code-toggle >}} + +Include a language designator in the content adapter's file name. + +```text +content/ +└── books/ + ├── _content.de.gotmpl + ├── _content.en.gotmpl + ├── _index.de.md + └── _index.en.md +``` + +### Translations by content directory + +With this site configuration: + +{{< code-toggle file=hugo >}} +[languages.en] +contentDir = 'content/en' +weight = 1 + +[languages.de] +contentDir = 'content/de' +weight = 2 +{{< /code-toggle >}} + +Create a single content adapter in each directory: + +```text +content/ +├── de/ +│ └── books/ +│ ├── _content.gotmpl +│ └── _index.md +└── en/ + └── books/ + ├── _content.gotmpl + └── _index.md +``` + +## Page collisions + +Two or more pages collide when they have the same publication path. Due to concurrency, the content of the published page is indeterminate. Consider this example: + +```text +content/ +└── books/ + ├── _content.gotmpl <-- content adapter + ├── _index.md + └── the-hunchback-of-notre-dame.md +``` + +If the content adapter also creates books/the-hunchback-of-notre-dame, the content of the published page is indeterminate. You can not define the processing order. + +To detect page collisions, use the `--printPathWarnings` flag when building your site. + +[content formats]: /content-management/formats/#classification +[front matter field]: /content-management/front-matter/#fields +[logical path]: /getting-started/glossary/#logical-path +[media type]: https://en.wikipedia.org/wiki/Media_type +[page kind]: /getting-started/glossary/#page-kind +[syntax]: /templates/introduction/ +[template functions]: /functions/ diff --cc docs/content/en/content-management/multilingual.md index 4529eb1c4,000000000..b8ba80dfd mode 100644,000000..100644 --- a/docs/content/en/content-management/multilingual.md +++ b/docs/content/en/content-management/multilingual.md @@@ -1,631 -1,0 +1,638 @@@ +--- +title: Multilingual mode +linkTitle: Multilingual +description: Localize your project for each language and region, including translations, images, dates, currencies, numbers, percentages, and collation sequence. Hugo's multilingual framework supports single-host and multihost configurations. +categories: [content management] +keywords: [multilingual,i18n,internationalization] +menu: + docs: + parent: content-management + weight: 230 +weight: 230 +toc: true +aliases: [/content/multilingual/,/tutorials/create-a-multilingual-site/] +--- + +## Configure languages + +This is the default language configuration: + +{{< code-toggle config=languages />}} + +In the above, `en` is the language key. + - {{% note %}} - Each language key must conform to the syntax described in [RFC 5646]. You must use hyphens to separate subtags. For example: ++ ++Language keys must conform to the syntax described in [RFC 5646]. For example: + +- `en` - - `en-GB` - - `pt-BR` ++- `en-US` + - [RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1 ++Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7] are also supported. Omit the `art-x-` prefix from the language key. For example: ++ ++- `hugolang` ++ ++{{% note %}} ++Private use subtags must not exceed 8 alphanumeric characters. +{{% /note %}} + ++[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1 ++[RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7 ++ +This is an example of a site configuration for a multilingual project. Any key not defined in a `languages` object will fall back to the global value in the root of your site configuration. + +{{< code-toggle file=hugo >}} +defaultContentLanguage = 'de' +defaultContentLanguageInSubdir = true + +[languages.de] +contentDir = 'content/de' +disabled = false +languageCode = 'de-DE' +languageDirection = 'ltr' +languageName = 'Deutsch' +title = 'Projekt Dokumentation' +weight = 1 + +[languages.de.params] +subtitle = 'Referenz, Tutorials und Erklärungen' + +[languages.en] +contentDir = 'content/en' +disabled = false +languageCode = 'en-US' +languageDirection = 'ltr' +languageName = 'English' +title = 'Project Documentation' +weight = 2 + +[languages.en.params] +subtitle = 'Reference, Tutorials, and Explanations' +{{< /code-toggle >}} + +defaultContentLanguage +: (`string`) The project's default language key, conforming to the syntax described in [RFC 5646]. This value must match one of the defined language keys. Examples: + +- `en` +- `en-GB` +- `pt-BR` + +defaultContentLanguageInSubdir +: (`bool`) If `true`, Hugo renders the default language site in a subdirectory matching the `defaultContentLanguage`. Default is `false`. + +contentDir +: (`string`) The content directory for this language. Omit if [translating by file name]. + +disabled +: (`bool`) If `true`, Hugo will not render content for this language. Default is `false`. + +languageCode +: (`string`) The language tag as described in [RFC 5646]. This value does not affect localization or URLs. Hugo uses this value to populate the `language` element in the [built-in RSS template], and the `lang` attribute of the `html` element in the [built-in alias template]. Examples: + +- `en` +- `en-GB` +- `pt-BR` + +languageDirection +: (`string`) The language direction, either left-to-right (`ltr`) or right-to-left (`rtl`). Use this value in your templates with the global [`dir`] HTML attribute. + +languageName +: (`string`) The language name, typically used when rendering a language switcher. + +title +: (`string`) The site title for this language (optional). + +weight +: (`int`) The language weight. When set to a non-zero value, this is the primary sort criteria for this language. + +[`dir`]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir +[built-in RSS template]: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml +[built-in alias template]: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/alias.html +[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1 +[translating by file name]: #translation-by-file-name + +### Changes in Hugo 0.112.0 + +{{< new-in 0.112.0 >}} + +In Hugo `v0.112.0` we consolidated all configuration options, and improved how the languages and their parameters are merged with the main configuration. But while testing this on Hugo sites out there, we received some error reports and reverted some of the changes in favor of deprecation warnings: + +1. `site.Language.Params` is deprecated. Use `site.Params` directly. +1. Adding custom parameters to the top level language configuration is deprecated. Define custom parameters within `languages.xx.params`. See `color` in the example below. + +{{< code-toggle file=hugo >}} + +title = "My blog" +languageCode = "en-us" + +[languages] +[languages.sv] +title = "Min blogg" +languageCode = "sv" +[languages.en.params] +color = "blue" +{{< /code-toggle >}} + +In the example above, all settings except `color` below `params` map to predefined configuration options in Hugo for the site and its language, and should be accessed via the documented accessors: + +```go-html-template +{{ site.Title }} +{{ site.LanguageCode }} +{{ site.Params.color }} +``` + +### Disable a language + +To disable a language within a `languages` object in your site configuration: + +{{< code-toggle file=hugo >}} +[languages.es] +disabled = true +{{< /code-toggle >}} + +To disable one or more languages in the root of your site configuration: + +{{< code-toggle file=hugo >}} +disableLanguages = ["es", "fr"] +{{< /code-toggle >}} + +To disable one or more languages using an environment variable: + +```sh +HUGO_DISABLELANGUAGES="es fr" hugo +``` + +Note that you cannot disable the default content language. + +### Configure multilingual multihost + + +Hugo supports multiple languages in a multihost configuration. This means you can configure a `baseURL` per `language`. + +{{% note %}} +If a `baseURL` is set on the `language` level, then all languages must have one and they must all be different. +{{% /note %}} + +Example: + +{{< code-toggle file=hugo >}} +[languages] + [languages.en] + baseURL = 'https://en.example.org/' + languageName = 'English' + title = 'In English' + weight = 2 + [languages.fr] + baseURL = 'https://fr.example.org' + languageName = 'Français' + title = 'En Français' + weight = 1 +{{}} + +With the above, the two sites will be generated into `public` with their own root: + +```text +public +├── en +└── fr +``` + +**All URLs (i.e `.Permalink` etc.) will be generated from that root. So the English home page above will have its `.Permalink` set to `https://example.org/`.** + +When you run `hugo server` we will start multiple HTTP servers. You will typically see something like this in the console: + +```text +Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1) fr +Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1) en +Press Ctrl+C to stop +``` + +Live reload and `--navigateToChanged` between the servers work as expected. + +## Translate your content + +There are two ways to manage your content translations. Both ensure each page is assigned a language and is linked to its counterpart translations. + +### Translation by file name + +Considering the following example: + +1. `/content/about.en.md` +2. `/content/about.fr.md` + +The first file is assigned the English language and is linked to the second. +The second file is assigned the French language and is linked to the first. + +Their language is __assigned__ according to the language code added as a __suffix to the file name__. + +By having the same **path and base file name**, the content pieces are __linked__ together as translated pages. + +{{% note %}} +If a file has no language code, it will be assigned the default language. +{{% /note %}} + +### Translation by content directory + +This system uses different content directories for each of the languages. Each language's content directory is set using the `contentDir` parameter. + +{{< code-toggle file=hugo >}} +languages: + en: + weight: 10 + languageName: "English" + contentDir: "content/english" + fr: + weight: 20 + languageName: "Français" + contentDir: "content/french" +{{< /code-toggle >}} + +The value of `contentDir` can be any valid path -- even absolute path references. The only restriction is that the content directories cannot overlap. + +Considering the following example in conjunction with the configuration above: + +1. `/content/english/about.md` +2. `/content/french/about.md` + +The first file is assigned the English language and is linked to the second. +The second file is assigned the French language and is linked to the first. + +Their language is __assigned__ according to the content directory they are __placed__ in. + +By having the same **path and basename** (relative to their language content directory), the content pieces are __linked__ together as translated pages. + +### Bypassing default linking + +Any pages sharing the same `translationKey` set in front matter will be linked as translated pages regardless of basename or location. + +Considering the following example: + +1. `/content/about-us.en.md` +2. `/content/om.nn.md` +3. `/content/presentation/a-propos.fr.md` + +{{< code-toggle >}} +translationKey: "about" +{{< /code-toggle >}} + +By setting the `translationKey` front matter parameter to `about` in all three pages, they will be __linked__ as translated pages. + +### Localizing permalinks + +Because paths and file names are used to handle linking, all translated pages will share the same URL (apart from the language subdirectory). + +To localize URLs: + +- For a regular page, set either [`slug`] or [`url`] in front matter +- For a section page, set [`url`] in front matter + +[`slug`]: /content-management/urls/#slug +[`url`]: /content-management/urls/#url + +For example, a French translation can have its own localized slug. + +{{< code-toggle file=content/about.fr.md fm=true >}} +title: A Propos +slug: "a-propos" +{{< /code-toggle >}} + +At render, Hugo will build both `/about/` and `/fr/a-propos/` without affecting the translation link. + +### Page bundles + +To avoid the burden of having to duplicate files, each Page Bundle inherits the resources of its linked translated pages' bundles except for the content files (Markdown files, HTML files etc...). + +Therefore, from within a template, the page will have access to the files from all linked pages' bundles. + +If, across the linked bundles, two or more files share the same basename, only one will be included and chosen as follows: + +* File from current language bundle, if present. +* First file found across bundles by order of language `Weight`. + +{{% note %}} +Page Bundle resources follow the same language assignment logic as content files, both by file name (`image.jpg`, `image.fr.jpg`) and by directory (`english/about/header.jpg`, `french/about/header.jpg`). +{{%/ note %}} + +## Reference translated content + +To create a list of links to translated content, use a template similar to the following: + +{{< code file=layouts/partials/i18nlist.html >}} +{{ if .IsTranslated }} +

{{ i18n "translations" }}

+ +{{ end }} +{{< /code >}} + +The above can be put in a `partial` (i.e., inside `layouts/partials/`) and included in any template. It will not print anything if there are no translations for a given page. + +The above also uses the [`i18n` function][i18func] described in the next section. + +### List all available languages + +`.AllTranslations` on a `Page` can be used to list all translations, including the page itself. On the home page it can be used to build a language navigator: + +{{< code file=layouts/partials/allLanguages.html >}} + +{{< /code >}} + +## Translation of strings + +See the [`lang.Translate`] template function. + +[`lang.Translate`]: /functions/lang/translate + +## Localization + +The following localization examples assume your site's primary language is English, with translations to French and German. + +{{< code-toggle file=hugo >}} +defaultContentLanguage = 'en' + +[languages] +[languages.en] +contentDir = 'content/en' +languageName = 'English' +weight = 1 +[languages.fr] +contentDir = 'content/fr' +languageName = 'Français' +weight = 2 +[languages.de] +contentDir = 'content/de' +languageName = 'Deutsch' +weight = 3 + +{{< /code-toggle >}} + +### Dates + +With this front matter: + +{{< code-toggle >}} +date = 2021-11-03T12:34:56+01:00 +{{< /code-toggle >}} + +And this template code: + +```go-html-template +{{ .Date | time.Format ":date_full" }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|Wednesday, November 3, 2021 +Français|mercredi 3 novembre 2021 +Deutsch|Mittwoch, 3. November 2021 + +See [`time.Format`] for details. + +### Currency + +With this template code: + +```go-html-template +{{ 512.5032 | lang.FormatCurrency 2 "USD" }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|$512.50 +Français|512,50 $US +Deutsch|512,50 $ + +See [lang.FormatCurrency] and [lang.FormatAccounting] for details. + +### Numbers + +With this template code: + +```go-html-template +{{ 512.5032 | lang.FormatNumber 2 }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|512.50 +Français|512,50 +Deutsch|512,50 + +See [lang.FormatNumber] and [lang.FormatNumberCustom] for details. + +### Percentages + +With this template code: + +```go-html-template +{{ 512.5032 | lang.FormatPercent 2 }} +``` + +The rendered page displays: + +Language|Value +:--|:-- +English|512.50% +Français|512,50 % +Deutsch|512,50 % + +See [lang.FormatPercent] for details. + +## Menus + +Localization of menu entries depends on how you define them: + +- When you define menu entries [automatically] using the section pages menu, you must use translation tables to localize each entry. +- When you define menu entries [in front matter], they are already localized based on the front matter itself. If the front matter values are insufficient, use translation tables to localize each entry. +- When you define menu entries [in site configuration], you must create language-specific menu entries under each language key. If the names of the menu entries are insufficient, use translation tables to localize each entry. + +### Create language-specific menu entries + +#### Method 1 -- Use a single configuration file + +For a simple menu with a small number of entries, use a single configuration file. For example: + +{{< code-toggle file=hugo >}} +[languages.de] +languageCode = 'de-DE' +languageName = 'Deutsch' +weight = 1 + +[[languages.de.menus.main]] +name = 'Produkte' +pageRef = '/products' +weight = 10 + +[[languages.de.menus.main]] +name = 'Leistungen' +pageRef = '/services' +weight = 20 + +[languages.en] +languageCode = 'en-US' +languageName = 'English' +weight = 2 + +[[languages.en.menus.main]] +name = 'Products' +pageRef = '/products' +weight = 10 + +[[languages.en.menus.main]] +name = 'Services' +pageRef = '/services' +weight = 20 +{{< /code-toggle >}} + +#### Method 2 -- Use a configuration directory + +With a more complex menu structure, create a [configuration directory] and split the menu entries into multiple files, one file per language. For example: + +```text +config/ +└── _default/ + ├── menus.de.toml + ├── menus.en.toml + └── hugo.toml +``` + +{{< code-toggle file=config/_default/menus.de >}} +[[main]] +name = 'Produkte' +pageRef = '/products' +weight = 10 +[[main]] +name = 'Leistungen' +pageRef = '/services' +weight = 20 +{{< /code-toggle >}} + +{{< code-toggle file=config/_default/menus.en >}} +[[main]] +name = 'Products' +pageRef = '/products' +weight = 10 +[[main]] +name = 'Services' +pageRef = '/services' +weight = 20 +{{< /code-toggle >}} + +[configuration directory]: /getting-started/configuration/#configuration-directory + +### Use translation tables + +When rendering the text that appears in menu each entry, the [example menu template] does this: + +```go-html-template +{{ or (T .Identifier) .Name | safeHTML }} +``` + +It queries the translation table for the current language using the menu entry's `identifier` and returns the translated string. If the translation table does not exist, or if the `identifier` key is not present in the translation table, it falls back to `name`. + +The `identifier` depends on how you define menu entries: + +- If you define the menu entry [automatically] using the section pages menu, the `identifier` is the page's `.Section`. +- If you define the menu entry [in site configuration] or [in front matter], set the `identifier` property to the desired value. + +For example, if you define menu entries in site configuration: + +{{< code-toggle file=hugo >}} +[[menus.main]] + identifier = 'products' + name = 'Products' + pageRef = '/products' + weight = 10 +[[menus.main]] + identifier = 'services' + name = 'Services' + pageRef = '/services' + weight = 20 +{{< / code-toggle >}} + +Create corresponding entries in the translation tables: + +{{< code-toggle file=i18n/de >}} +products = 'Produkte' +services = 'Leistungen' +{{< / code-toggle >}} + +[example menu template]: /templates/menu/#example +[automatically]: /content-management/menus/#define-automatically +[in front matter]: /content-management/menus/#define-in-front-matter +[in site configuration]: /content-management/menus/#define-in-site-configuration + +## Missing translations + +If a string does not have a translation for the current language, Hugo will use the value from the default language. If no default value is set, an empty string will be shown. + +While translating a Hugo website, it can be handy to have a visual indicator of missing translations. The [`enableMissingTranslationPlaceholders` configuration option][config] will flag all untranslated strings with the placeholder `[i18n] identifier`, where `identifier` is the id of the missing translation. + +{{% note %}} +Hugo will generate your website with these missing translation placeholders. It might not be suitable for production environments. +{{% /note %}} + +For merging of content from other languages (i.e. missing content translations), see [lang.Merge]. + +To track down missing translation strings, run Hugo with the `--printI18nWarnings` flag: + +```sh +hugo --printI18nWarnings | grep i18n +i18n|MISSING_TRANSLATION|en|wordCount +``` + +## Multilingual themes support + +To support Multilingual mode in your themes, some considerations must be taken for the URLs in the templates. If there is more than one language, URLs must meet the following criteria: + +* Come from the built-in `.Permalink` or `.RelPermalink` +* Be constructed with the [`relLangURL`] or [`absLangURL`] template function, or be prefixed with `{{ .LanguagePrefix }}` + +If there is more than one language defined, the `LanguagePrefix` method will return `/en` (or whatever the current language is). If not enabled, it will be an empty string (and is therefore harmless for single-language Hugo websites). + +## Generate multilingual content with `hugo new content` + +If you organize content with translations in the same directory: + +```sh +hugo new content post/test.en.md +hugo new content post/test.de.md +``` + +If you organize content with translations in different directories: + +```sh +hugo new content content/en/post/test.md +hugo new content content/de/post/test.md +``` + +[`abslangurl`]: /functions/urls/abslangurl/ +[config]: /getting-started/configuration/ +[go-i18n-source]: https://github.com/nicksnyder/go-i18n +[go-i18n]: https://github.com/nicksnyder/go-i18n +[Hugo Multilingual Part 1: Content translation]: https://regisphilibert.com/blog/2018/08/hugo-multilingual-part-1-managing-content-translation/ +[i18func]: /functions/lang/translate/ +[lang.FormatAccounting]: /functions/lang/formataccounting/ +[lang.FormatCurrency]: /functions/lang/formatcurrency/ +[lang.FormatNumber]: /functions/lang/formatnumber/ +[lang.FormatNumberCustom]: /functions/lang/formatnumbercustom/ +[lang.FormatPercent]: /functions/lang/formatpercent/ +[lang.Merge]: /functions/lang/merge/ +[menus]: /content-management/menus/ +[OS environment]: /getting-started/configuration/#configure-with-environment-variables +[`rellangurl`]: /functions/urls/rellangurl/ +[`time.Format`]: /functions/time/format/ diff --cc docs/content/en/content-management/page-resources.md index 6f746488c,000000000..4f902a67f mode 100644,000000..100644 --- a/docs/content/en/content-management/page-resources.md +++ b/docs/content/en/content-management/page-resources.md @@@ -1,309 -1,0 +1,310 @@@ +--- +title: Page resources - description: Page resources -- images, other pages, documents, etc. -- have page-relative URLs and their own metadata. ++description: Use page resources to logically associate assets with a page. +categories: [content management] +keywords: [bundle,content,resources] +menu: + docs: + parent: content-management + weight: 80 +weight: 80 +toc: true +--- + +Page resources are only accessible from [page bundles](/content-management/page-bundles), those directories with `index.md` or +`_index.md` files at their root. Page resources are only available to the +page with which they are bundled. + +In this example, `first-post` is a page bundle with access to 10 page resources including audio, data, documents, images, and video. Although `second-post` is also a page bundle, it has no page resources and is unable to directly access the page resources associated with `first-post`. + +```text +content +└── post + ├── first-post + │ ├── images + │ │ ├── a.jpg + │ │ ├── b.jpg + │ │ └── c.jpg + │ ├── index.md (root of page bundle) + │ ├── latest.html + │ ├── manual.json + │ ├── notice.md + │ ├── office.mp3 + │ ├── pocket.mp4 + │ ├── rating.pdf + │ └── safety.txt + └── second-post + └── index.md (root of page bundle) +``` + - ## Properties ++## Examples + - ResourceType - : The main type of the resource's [Media Type](/templates/output-formats/#media-types). For example, a file of MIME type `image/jpeg` has the ResourceType `image`. A `Page` will have `ResourceType` with value `page`. ++Use any of these methods on a `Page` object to capture page resources: + - Name - : Default value is the file name (relative to the owning page). Can be set in front matter. ++ - [`Resources.ByType`] ++ - [`Resources.Get`] ++ - [`Resources.GetMatch`] ++ - [`Resources.Match`] + - Title - : Default value is the same as `.Name`. Can be set in front matter. ++ Once you have captured a resource, use any of the applicable [`Resource`] methods to return a value or perform an action. + - Permalink - : The absolute URL to the resource. Resources of type `page` will have no value. ++[`Resource`]: /methods/resource ++[`Resources.ByType`]: /methods/page/resources#bytype ++[`Resources.GetMatch`]: /methods/page/resources#getmatch ++[`Resources.Get`]: /methods/page/resources#get ++[`Resources.Match`]: /methods/page/resources#match + - RelPermalink - : The relative URL to the resource. Resources of type `page` will have no value. ++The following examples assume this content structure: + - Content - : The content of the resource itself. For most resources, this returns a string - with the contents of the file. Use this to create inline resources. ++```text ++content/ ++└── example/ ++ ├── data/ ++ │ └── books.json <-- page resource ++ ├── images/ ++ │ ├── a.jpg <-- page resource ++ │ └── b.jpg <-- page resource ++ ├── snippets/ ++ │ └── text.md <-- page resource ++ └── index.md ++``` + - ```go-html-template - {{ with .Resources.GetMatch "script.js" }} - - {{ end }} ++Render a single image, and throw an error if the file does not exist: + - {{ with .Resources.GetMatch "style.css" }} - - {{ end }} - - {{ with .Resources.GetMatch "img.png" }} - ++```go-html-template ++{{ $path := "images/a.jpg" }} ++{{ with .Resources.Get $path }} ++ ++{{ else }} ++ {{ errorf "Unable to get page resource %q" $path }} +{{ end }} +``` + - MediaType.Type - : The media type (formerly known as a MIME type) of the resource (e.g., `image/jpeg`). - - MediaType.MainType - : The main type of the resource's media type (e.g., `image`). - - MediaType.SubType - : The subtype of the resource's type (e.g., `jpeg`). This may or may not correspond to the file suffix. - - MediaType.Suffixes - : A slice of possible file suffixes for the resource's media type (e.g., `[jpg jpeg jpe jif jfif]`). - - ## Methods - - ByType - : Returns the page resources of the given type. ++Render all images, resized to 300 px wide: + +```go-html-template - {{ .Resources.ByType "image" }} ++{{ range .Resources.ByType "image" }} ++ {{ with .Resize "300x" }} ++ ++ {{ end }} ++{{ end }} +``` - Match - : Returns all the page resources (as a slice) whose `Name` matches the given Glob pattern ([examples](https://github.com/gobwas/glob/blob/master/readme.md)). The matching is case-insensitive. ++ ++Render the markdown snippet: + +```go-html-template - {{ .Resources.Match "images/*" }} ++{{ with .Resources.Get "snippets/text.md" }} ++ {{ .Content }} ++{{ end }} +``` + - GetMatch - : Same as `Match` but will return the first match. - - ### Pattern matching ++List the titles in the data file, and throw an error if the file does not exist. + - ```go - // Using Match/GetMatch to find this images/sunset.jpg ? - .Resources.Match "images/sun*" ✅ - .Resources.Match "**/sunset.jpg" ✅ - .Resources.Match "images/*.jpg" ✅ - .Resources.Match "**.jpg" ✅ - .Resources.Match "*" 🚫 - .Resources.Match "sunset.jpg" 🚫 - .Resources.Match "*sunset.jpg" 🚫 ++```go-html-template ++{{ $path := "data/books.json" }} ++{{ with .Resources.Get $path }} ++ {{ with . | transform.Unmarshal }} ++

Books:

++ ++ {{ end }} ++{{ else }} ++ {{ errorf "Unable to get page resource %q" $path }} ++{{ end }} +``` + +## Metadata + +The page resources' metadata is managed from the corresponding page's front matter with an array/table parameter named `resources`. You can batch assign values using [wildcards](https://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm). + +{{% note %}} +Resources of type `page` get `Title` etc. from their own front matter. +{{% /note %}} + +name - : Sets the value returned in `Name`. ++: (`string`) Sets the value returned in `Name`. + +{{% note %}} +The methods `Match`, `Get` and `GetMatch` use `Name` to match the resources. +{{% /note %}} + +title - : Sets the value returned in `Title` ++: (`string`) Sets the value returned in `Title` + +params - : A map of custom key-value pairs. ++: (`map`) A map of custom key-value pairs. + +### Resources metadata example + - {{< code-toggle >}} ++{{< code-toggle file=content/example.md fm=true >}} +title: Application +date : 2018-01-25 +resources : +- src : "images/sunset.jpg" + name : "header" +- src : "documents/photo_specs.pdf" + title : "Photo Specifications" + params: + icon : "photo" +- src : "documents/guide.pdf" + title : "Instruction Guide" +- src : "documents/checklist.pdf" + title : "Document Checklist" +- src : "documents/payment.docx" + title : "Proof of Payment" +- src : "**.pdf" + name : "pdf-file-:counter" + params : + icon : "pdf" +- src : "**.docx" + params : + icon : "word" +{{}} + +From the example above: + +- `sunset.jpg` will receive a new `Name` and can now be found with `.GetMatch "header"`. +- `documents/photo_specs.pdf` will get the `photo` icon. +- `documents/checklist.pdf`, `documents/guide.pdf` and `documents/payment.docx` will get `Title` as set by `title`. +- Every `PDF` in the bundle except `documents/photo_specs.pdf` will get the `pdf` icon. +- All `PDF` files will get a new `Name`. The `name` parameter contains a special placeholder [`:counter`](#the-counter-placeholder-in-name-and-title), so the `Name` will be `pdf-file-1`, `pdf-file-2`, `pdf-file-3`. +- Every docx in the bundle will receive the `word` icon. + +{{% note %}} - The __order matters__ --- Only the **first set** values of the `title`, `name` and `params`-**keys** will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule. ++The order matters; only the first set values of the `title`, `name` and `params` keys will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule. +{{% /note %}} + +### The `:counter` placeholder in `name` and `title` + +The `:counter` is a special placeholder recognized in `name` and `title` parameters `resources`. + +The counter starts at 1 the first time they are used in either `name` or `title`. + +For example, if a bundle has the resources `photo_specs.pdf`, `other_specs.pdf`, `guide.pdf` and `checklist.pdf`, and the front matter has specified the `resources` as: + +{{< code-toggle file=content/inspections/engine/index.md fm=true >}} +title = 'Engine inspections' +[[resources]] + src = "*specs.pdf" + title = "Specification #:counter" +[[resources]] + src = "**.pdf" + name = "pdf-file-:counter" +{{}} + +the `Name` and `Title` will be assigned to the resource files as follows: + +| Resource file | `Name` | `Title` | +|-------------------|-------------------|-----------------------| +| checklist.pdf | `"pdf-file-1.pdf` | `"checklist.pdf"` | +| guide.pdf | `"pdf-file-2.pdf` | `"guide.pdf"` | +| other\_specs.pdf | `"pdf-file-3.pdf` | `"Specification #1"` | +| photo\_specs.pdf | `"pdf-file-4.pdf` | `"Specification #2"` | + +## Multilingual + +{{< new-in 0.123.0 >}} + +By default, with a multilingual single-host site, Hugo does not duplicate shared page resources when building the site. + +{{% note %}} +This behavior is limited to Markdown content. Shared page resources for other [content formats] are copied into each language bundle. + +[content formats]: /content-management/formats/ +{{% /note %}} + +Consider this site configuration: + +{{< code-toggle file=hugo >}} +defaultContentLanguage = 'de' +defaultContentLanguageInSubdir = true + +[languages.de] +languageCode = 'de-DE' +languageName = 'Deutsch' +weight = 1 + +[languages.en] +languageCode = 'en-US' +languageName = 'English' +weight = 2 +{{< /code-toggle >}} + +And this content: + +```text +content/ +└── my-bundle/ + ├── a.jpg <-- shared page resource + ├── b.jpg <-- shared page resource + ├── c.de.jpg + ├── c.en.jpg + ├── index.de.md + └── index.en.md +``` + +With v0.122.0 and earlier, Hugo duplicated the shared page resources, creating copies for each language: + +```text +public/ +├── de/ +│ ├── my-bundle/ +│ │ ├── a.jpg <-- shared page resource +│ │ ├── b.jpg <-- shared page resource +│ │ ├── c.de.jpg +│ │ └── index.html +│ └── index.html +├── en/ +│ ├── my-bundle/ +│ │ ├── a.jpg <-- shared page resource (duplicate) +│ │ ├── b.jpg <-- shared page resource (duplicate) +│ │ ├── c.en.jpg +│ │ └── index.html +│ └── index.html +└── index.html + +``` + +With v0.123.0 and later, Hugo places the shared resources in the page bundle for the default content language: + +```text +public/ +├── de/ +│ ├── my-bundle/ +│ │ ├── a.jpg <-- shared page resource +│ │ ├── b.jpg <-- shared page resource +│ │ ├── c.de.jpg +│ │ └── index.html +│ └── index.html +├── en/ +│ ├── my-bundle/ +│ │ ├── c.en.jpg +│ │ └── index.html +│ └── index.html +└── index.html +``` + +This approach reduces build times, storage requirements, bandwidth consumption, and deployment times, ultimately reducing cost. + +{{% note %}} +To resolve Markdown link and image destinations to the correct location, you must use link and image render hooks that capture the page resource with the [`Resources.Get`] method, and then invoke its [`RelPermalink`] method. + +By default, with multilingual single-host sites, Hugo enables its [embedded link render hook] and [embedded image render hook] to resolve Markdown link and image destinations. + +You may override the embedded render hooks as needed, provided they capture the resource as described above. + +[embedded link render hook]: /render-hooks/links/#default +[embedded image render hook]: /render-hooks/images/#default +[`Resources.Get`]: /methods/page/resources/#get +[`RelPermalink`]: /methods/resource/relpermalink/ +{{% /note %}} + +Although duplicating shared page resources is inefficient, you can enable this feature in your site configuration if desired: + +{{< code-toggle file=hugo >}} +[markup.goldmark] +duplicateResourceFiles = true +{{< /code-toggle >}} diff --cc docs/content/en/contribute/development.md index f6ff44ced,000000000..e4b183e93 mode 100644,000000..100644 --- a/docs/content/en/contribute/development.md +++ b/docs/content/en/contribute/development.md @@@ -1,174 -1,0 +1,174 @@@ +--- +title: Development +description: Contribute to the development of Hugo. +categories: [contribute] +keywords: [development] +menu: + docs: + parent: contribute + weight: 20 +weight: 20 +toc: true +--- + +## Introduction + +You can contribute to the Hugo project by: + +- Answering questions on the [forum] +- Improving the [documentation] +- Monitoring the [issue queue] +- Creating or improving [themes] +- Squashing [bugs] + +Please submit documentation issues and pull requests to the [documentation repository]. + +If you have an idea for an enhancement or new feature, create a new topic on the [forum] in the "Feature" category. This will help you to: + +- Determine if the capability already exists +- Measure interest +- Refine the concept + +If there is sufficient interest, [create a proposal]. Do not submit a pull request until the project lead accepts the proposal. + +For a complete guide to contributing to Hugo, see the [Contribution Guide]. + +[bugs]: https://github.com/gohugoio/hugo/issues?q=is%3Aopen+is%3Aissue+label%3ABug +[contributing]: CONTRIBUTING.md +[create a proposal]: https://github.com/gohugoio/hugo/issues/new?labels=Proposal%2C+NeedsTriage&template=feature_request.md +[documentation repository]: https://github.com/gohugoio/hugoDocs +[documentation]: https://gohugo.io/documentation +[forum]: https://discourse.gohugo.io +[issue queue]: https://github.com/gohugoio/hugo/issues +[themes]: https://themes.gohugo.io/ +[contribution guide]: https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md + +## Prerequisites + +To build the extended edition of Hugo from source you must: + +1. Install [Git] - 1. Install [Go] version 1.20 or later ++1. Install [Go] version 1.23.0 or later +1. Install a C compiler, either [GCC] or [Clang] +1. Update your `PATH` environment variable as described in the [Go documentation] + +[Clang]: https://clang.llvm.org/ +[GCC]: https://gcc.gnu.org/ +[Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git +[Go documentation]: https://go.dev/doc/code#Command +[Go]: https://go.dev/doc/install + +{{% note %}} +See these [detailed instructions](https://discourse.gohugo.io/t/41370) to install GCC on Windows. +{{% /note %}} + +## GitHub workflow + +{{% note %}} +This section assumes that you have a working knowledge of Go, Git and GitHub, and are comfortable working on the command line. +{{% /note %}} + +Use this workflow to create and submit pull requests. + +Step 1 +: Fork the [project repository]. + +[project repository]: https://github.com/gohugoio/hugo/ + +Step 2 +: Clone your fork. + +Step 3 +: Create a new branch with a descriptive name that includes the corresponding issue number. + +For a new feature: + +```sh +git checkout -b feat/implement-some-feature-99999 +``` + +For a bug fix: + +```sh +git checkout -b fix/fix-some-bug-99999 +``` + +Step 4 +: Make changes. + +Step 5 +: Compile and install: + +```text +CGO_ENABLED=1 go install -tags extended +``` + +Step 6 +: Test your changes: + +```text +go test ./... +``` + +Step 7 +: 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. +- Optionally, provide a detailed description where each line is 80 characters or less, followed by a blank line. +- Add one or more "Fixes" or "Closes" keywords, each on its own line, referencing the [issues] addressed by this change. + +[issues]: https://github.com/gohugoio/hugo/issues + +For example: + +```sh +git commit -m "tpl/strings: Create wrap function + +The strings.Wrap function wraps a string into one or more lines, +splitting the string after the given number of characters, but not +splitting in the middle of a word. + +Fixes #99998 +Closes #99999" +``` + +See the [commit message guidelines] for details. + +[commit message guidelines]: https://github.com/gohugoio/hugo/blob/master/CONTRIBUTING.md#git-commit-message-guidelines + +Step 8 +: Push the new branch to your fork of the documentation repository. + +Step 9 +: Visit the [project repository] and create a pull request (PR). + +Step 10 +: A project maintainer will review your PR and may request changes. You may delete your branch after the maintainer merges your PR. + +## Building from source + +You can build, install, and test Hugo at any point in its development history. The examples below build and install the extended version of Hugo. + +To build and install the latest release: + +```sh +CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest +``` + +To build and install a specific release: + +```sh +CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@v0.128.0 +``` + +To build and install at the latest commit on the master branch: + +```sh +CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@master +``` + +To build and install at a specific commit: + +```sh +CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@0851c17 +``` diff --cc docs/content/en/functions/go-template/_common/truthy-falsy.md index c8fc9e09e,000000000..c41bb6561 mode 100644,000000..100644 --- a/docs/content/en/functions/go-template/_common/truthy-falsy.md +++ b/docs/content/en/functions/go-template/_common/truthy-falsy.md @@@ -1,5 -1,0 +1,7 @@@ +--- +# Do not remove front matter. +--- + - In Go templates, the falsy values are `false`, `0`, any nil pointer or interface value, and any array, slice, map, or string of length zero. Everything else is truthy. ++The falsy values are `false`, `0`, any `nil` pointer or interface value, any array, slice, map, or string of length zero, and zero `time.Time` values. ++ ++Everything else is truthy. diff --cc docs/content/en/functions/go-template/if.md index 19c887f25,000000000..9fdf80e99 mode 100644,000000..100644 --- a/docs/content/en/functions/go-template/if.md +++ b/docs/content/en/functions/go-template/if.md @@@ -1,54 -1,0 +1,54 @@@ +--- +title: if +description: Executes the block if the expression is truthy. +categories: [] +keywords: [] +action: + aliases: [] + related: + - functions/go-template/with + - functions/go-template/else + - functions/go-template/end + - functions/collections/IsSet + returnType: + signatures: [if EXPR] +--- + +{{% include "functions/go-template/_common/truthy-falsy.md" %}} + +```go-html-template +{{ $var := "foo" }} +{{ if $var }} + {{ $var }} → foo +{{ end }} +``` + +Use with the [`else`] statement: + +```go-html-template +{{ $var := "foo" }} +{{ if $var }} + {{ $var }} → foo +{{ else }} + {{ print "var is falsy" }} +{{ end }} +``` + - Use `else if` to check multiple conditions. ++Use `else if` to check multiple conditions: + +```go-html-template +{{ $var := 12 }} +{{ if eq $var 6 }} + {{ print "var is 6" }} +{{ else if eq $var 7 }} + {{ print "var is 7" }} +{{ else if eq $var 42 }} + {{ print "var is 42" }} +{{ else }} + {{ print "var is something else" }} +{{ end }} +``` + +{{% include "functions/go-template/_common/text-template.md" %}} + +[`else`]: /functions/go-template/else/ diff --cc docs/content/en/functions/go-template/with.md index 3a73d54bb,000000000..3d628e28d mode 100644,000000..100644 --- a/docs/content/en/functions/go-template/with.md +++ b/docs/content/en/functions/go-template/with.md @@@ -1,87 -1,0 +1,101 @@@ +--- +title: with +description: Binds context (the dot) to the expression and executes the block if expression is truthy. +categories: [] +keywords: [] +action: + aliases: [] + related: + - functions/go-template/if + - functions/go-template/else + - functions/go-template/end + - functions/collections/IsSet + returnType: + signatures: [with EXPR] +aliases: [/functions/with] +toc: true +--- + +{{% include "functions/go-template/_common/truthy-falsy.md" %}} + +```go-html-template +{{ $var := "foo" }} +{{ with $var }} + {{ . }} → foo +{{ end }} +``` + +Use with the [`else`] statement: + +```go-html-template +{{ $var := "foo" }} +{{ with $var }} + {{ . }} → foo +{{ else }} + {{ print "var is falsy" }} +{{ end }} +``` + ++Use `else with` to check multiple conditions: ++ ++```go-html-template ++{{ $v1 := 0 }} ++{{ $v2 := 42 }} ++{{ with $v1 }} ++ {{ . }} ++{{ else with $v2 }} ++ {{ . }} → 42 ++{{ else }} ++ {{ print "v1 and v2 are falsy" }} ++{{ end }} ++``` ++ +Initialize a variable, scoped to the current block: + +```go-html-template +{{ with $var := 42 }} + {{ . }} → 42 + {{ $var }} → 42 +{{ end }} +{{ $var }} → undefined +``` + +## Understanding context + +At the top of a page template, the [context] (the dot) is a `Page` object. Inside of the `with` block, the context is bound to the value passed to the `with` statement. + +With this contrived example: + +```go-html-template +{{ with 42 }} + {{ .Title }} +{{ end }} +``` + +Hugo will throw an error: + + can't evaluate field Title in type int + +The error occurs because we are trying to use the `.Title` method on an integer instead of a `Page` object. Inside of the `with` block, if we want to render the page title, we need to get the context passed into the template. + +{{% note %}} +Use the `$` to get the context passed into the template. +{{% /note %}} + +This template will render the page title as desired: + +```go-html-template +{{ with 42 }} + {{ $.Title }} +{{ end }} +``` + +{{% note %}} +Gaining a thorough understanding of context is critical for anyone writing template code. +{{% /note %}} + +[context]: /getting-started/glossary/#context + +{{% include "functions/go-template/_common/text-template.md" %}} + +[`else`]: /functions/go-template/else/ diff --cc docs/content/en/functions/transform/ToMath.md index 000000000,000000000..db93a7382 new file mode 100644 --- /dev/null +++ b/docs/content/en/functions/transform/ToMath.md @@@ -1,0 -1,0 +1,112 @@@ ++--- ++title: transform.ToMath ++description: Renders a math expression using KaTeX. ++categories: [] ++keywords: [] ++action: ++ aliases: [] ++ related: ++ - content-management/mathematics ++ returnType: types.Result[template.HTML] ++ signatures: ['transform.ToMath EXPRESSION [OPTIONS]'] ++aliases: [/functions/tomath] ++toc: true ++--- ++ ++{{< new-in "0.132.0" >}} ++ ++{{% note %}} ++This feature was introduced in Hugo 0.132.0 and is marked as experimental. ++ ++This does not mean that it's going to be removed, but this is our first use of WASI/Wasm in Hugo, and we need to see how it [works in the wild](https://github.com/gohugoio/hugo/issues/12736) before we can set it in stone. ++{{% /note %}} ++ ++## Arguments ++ ++EXPRESSION ++: The math expression to render using KaTeX. ++ ++OPTIONS ++: A map of zero or more options. ++ ++## Options ++ ++These are a subset of the [KaTeX options]. ++ ++output ++: (`string`). Determines the markup language of the output. One of `html`, `mathml`, or `htmlAndMathml`. Default is `mathml`. ++ ++ ++ ++ With `html` and `htmlAndMathml` you must include KaTeX CSS within the `head` element of your base template. For example: ++ ++ ```html ++ ++ ... ++ ++ ... ++ ++ ``` ++ ++displayMode ++: (`bool`) If `true` render in display mode, else render in inline mode. Default is `false`. ++ ++leqno ++: (`bool`) If `true` render with the equation numbers on the left. Default is `false`. ++ ++fleqn ++: (`bool`) If `true` render flush left with a 2em left margin. Default is `false`. ++ ++minRuleThickness ++: (`float`) The minimum thickness of the fraction lines in `em`. Default is `0.04`. ++ ++macros ++: (`map`) A map of macros to be used in the math expression. Default is `{}`. ++ ++throwOnError ++: (`bool`) If `true` throw a `ParseError` when KaTeX encounters an unsupported command or invalid LaTex. See [error handling]. Default is `true`. ++ ++errorColor ++: (`string`) The color of the error messages expressed as an RGB [hexadecimal color]. Default is `#cc0000`. ++ ++## Examples ++ ++### Basic ++ ++```go-html-template ++{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }} ++``` ++ ++### Macros ++ ++```go-html-template ++{{ $macros := dict ++ "\\addBar" "\\bar{#1}" ++ "\\bold" "\\mathbf{#1}" ++}} ++{{ $opts := dict "macros" $macros }} ++{{ transform.ToMath "\\addBar{y} + \\bold{H}" $opts }} ++``` ++ ++## Error handling ++ ++There are 3 ways to handle errors from KaTeX: ++ ++1. Let KaTeX throw an error and make the build fail. This is the default behavior. ++1. Handle the error in your template. See the render hook example below. ++1. Set the `throwOnError` option to `false` to make KaTeX render the expression as an error instead of throwing an error. See [options]. ++ ++{{< code file=layouts/_default/_markup/render-passthrough-inline.html copy=true >}} ++{{ with transform.ToMath .Inner }} ++ {{ with .Err }} ++ {{ errorf "Failed to render KaTeX: %q. See %s" . $.Position }} ++ {{ else }} ++ {{ . }} ++ {{ end }} ++{{ end }} ++{{- /* chomp trailing newline */ -}} ++{{< /code >}} ++ ++[error handling]: #error-handling ++[KaTeX options]: https://katex.org/docs/options.html ++[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color diff --cc docs/content/en/getting-started/configuration-markup.md index 4ba4a60fe,000000000..0046ff1ed mode 100644,000000..100644 --- a/docs/content/en/getting-started/configuration-markup.md +++ b/docs/content/en/getting-started/configuration-markup.md @@@ -1,342 -1,0 +1,387 @@@ +--- +title: Configure markup +description: Configure rendering of markup to HTML. +categories: [getting started,fundamentals] +keywords: [markup,markdown,goldmark,asciidoc,asciidoctor,highlighting] +menu: + docs: + parent: getting-started + weight: 50 +weight: 50 +slug: configuration-markup +toc: true +--- + +## Default handler + +Hugo uses [Goldmark] to render Markdown to HTML. + +{{< code-toggle file=hugo >}} +[markup] +defaultMarkdownHandler = 'goldmark' +{{< /code-toggle >}} + +Files with the `.md` or `.markdown` extension are processed as Markdown, provided that you have not specified a different [content format] using the `markup` field in front matter. + +To use a different renderer for Markdown files, specify one of `asciidocext`, `org`, `pandoc`, or `rst` in your site configuration. + +defaultMarkdownHandler|Description +:--|:-- +`asciidocext`|[AsciiDoc] +`goldmark`|[Goldmark] +`org`|[Emacs Org Mode] +`pandoc`|[Pandoc] +`rst`|[reStructuredText] + +To use AsciiDoc, Pandoc, or reStructuredText you must install the relevant renderer and update your [security policy]. + +{{% note %}} +Unless you need a unique capability provided by one of the alternate Markdown handlers, we strongly recommend that you use the default setting. Goldmark is fast, well maintained, conforms to the [CommonMark] specification, and is compatible with [GitHub Flavored Markdown] (GFM). + +[commonmark]: https://spec.commonmark.org/0.30/ +[github flavored markdown]: https://github.github.com/gfm/ +{{% /note %}} + +[asciidoc]: https://asciidoc.org/ +[content format]: /content-management/formats/#formats +[emacs org mode]: https://orgmode.org/ +[goldmark]: https://github.com/yuin/goldmark/ +[pandoc]: https://pandoc.org/ +[restructuredtext]: https://docutils.sourceforge.io/rst.html +[security policy]: /about/security/#security-policy + +## Goldmark + +This is the default configuration for the Goldmark Markdown renderer: + +{{< code-toggle config=markup.goldmark />}} + +### Goldmark extensions + +The extensions below, excluding Extras and Passthrough, are enabled by default. + +Extension|Documentation|Enabled +:--|:--|:-: +cjk|[Goldmark Extensions: CJK]|:heavy_check_mark: +definitionList|[PHP Markdown Extra: Definition lists]|:heavy_check_mark: +extras|[Hugo Goldmark Extensions: Extras]| +footnote|[PHP Markdown Extra: Footnotes]|:heavy_check_mark: +linkify|[GitHub Flavored Markdown: Autolinks]|:heavy_check_mark: +passthrough|[Hugo Goldmark Extensions: Passthrough]| +strikethrough|[GitHub Flavored Markdown: Strikethrough]|:heavy_check_mark: +table|[GitHub Flavored Markdown: Tables]|:heavy_check_mark: +taskList|[GitHub Flavored Markdown: Task list items]|:heavy_check_mark: +typographer|[Goldmark Extensions: Typographer]|:heavy_check_mark: + +[GitHub Flavored Markdown: Autolinks]: https://github.github.com/gfm/#autolinks-extension- +[GitHub Flavored Markdown: Strikethrough]: https://github.github.com/gfm/#strikethrough-extension- +[GitHub Flavored Markdown: Tables]: https://github.github.com/gfm/#tables-extension- +[GitHub Flavored Markdown: Task list items]: https://github.github.com/gfm/#task-list-items-extension- +[Goldmark Extensions: CJK]: https://github.com/yuin/goldmark?tab=readme-ov-file#cjk-extension +[Goldmark Extensions: Typographer]: https://github.com/yuin/goldmark?tab=readme-ov-file#typographer-extension +[Hugo Goldmark Extensions: Extras]: https://github.com/gohugoio/hugo-goldmark-extensions?tab=readme-ov-file#extras-extension +[Hugo Goldmark Extensions: Passthrough]: https://github.com/gohugoio/hugo-goldmark-extensions?tab=readme-ov-file#passthrough-extension +[PHP Markdown Extra: Definition lists]: https://michelf.ca/projects/php-markdown/extra/#def-list +[PHP Markdown Extra: Footnotes]: https://michelf.ca/projects/php-markdown/extra/#footnotes + +#### Extras + +{{< new-in 0.126.0 >}} + +Enable [deleted text], [inserted text], [mark text], [subscript], and [superscript] elements in Markdown. + +Element|Markdown|Rendered +:--|:--|:-- +Deleted text|`~~foo~~`|`foo` +Inserted text|`++bar++`|`bar` +Mark text|`==baz==`|`baz` +Subscript|`H~2~O`|`H2O` +Superscript|`1^st^`|`1st` + +[deleted text]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del +[inserted text]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins +[mark text]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark +[subscript]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub +[superscript]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup + +To avoid a conflict when enabling the Hugo Goldmark Extras subscript extension, if you want to render subscript and strikethrough text concurrently you must: + +1. Disable the Goldmark strikethrough extension +2. Enable the Hugo Goldmark Extras delete extension + +For example: + +{{< code-toggle file=hugo >}} +[markup.goldmark.extensions] +strikethrough = false + +[markup.goldmark.extensions.extras.delete] +enable = true + +[markup.goldmark.extensions.extras.subscript] +enable = true +{{< /code-toggle >}} + +#### Passthrough + +{{< new-in 0.122.0 >}} + +Enable the passthrough extension to include mathematical equations and expressions in Markdown using LaTeX or TeX typesetting syntax. See [mathematics in Markdown] for details. + +[mathematics in Markdown]: content-management/mathematics/ + +#### Typographer + +The Typographer extension replaces certain character combinations with HTML entities as specified below: + +Markdown|Replaced by|Description +:--|:--|:-- +`...`|`…`|horizontal ellipsis +`'`|`’`|apostrophe +`--`|`–`|en dash +`---`|`—`|em dash +`«`|`«`|left angle quote +`“`|`“`|left double quote +`‘`|`‘`|left single quote +`»`|`»`|right angle quote +`”`|`”`|right double quote +`’`|`’`|right single quote + +### Goldmark settings explained + +Most of the Goldmark settings above are self-explanatory, but some require explanation. + +###### duplicateResourceFiles + +{{< new-in 0.123.0 >}} + +(`bool`) If `true`, shared page resources on multilingual single-host sites will be duplicated for each language. See [multilingual page resources] for details. Default is `false`. + +[multilingual page resources]: /content-management/page-resources/#multilingual + +{{% note %}} +With multilingual single-host sites, setting this parameter to `false` will enable Hugo's [embedded link render hook] and [embedded image render hook]. This is the default configuration for multilingual single-host sites. + +[embedded image render hook]: /render-hooks/images/#default +[embedded link render hook]: /render-hooks/links/#default +{{% /note %}} + +###### parser.wrapStandAloneImageWithinParagraph + +(`bool`) If `true`, image elements without adjacent content will be wrapped within a `p` element when rendered. This is the default Markdown behavior. Set to `false` when using an [image render hook] to render standalone images as `figure` elements. Default is `true`. + +[image render hook]: /render-hooks/images/ + +###### parser.autoHeadingIDType + +(`string`) The strategy used to automatically generate heading `id` attributes, one of `github`, `github-ascii` or `blackfriday`. + +- `github` produces GitHub-compatible `id` attributes +- `github-ascii` drops any non-ASCII characters after accent normalization +- `blackfriday` produces `id` attributes compatible with the Blackfriday Markdown renderer + +This is also the strategy used by the [anchorize](/functions/urls/anchorize) template function. Default is `github`. + +###### parser.attribute.block + +(`bool`) If `true`, enables [Markdown attributes] for block elements. Default is `false`. + +[Markdown attributes]: /content-management/markdown-attributes/ + +###### parser.attribute.title + +(`bool`) If `true`, enables [Markdown attributes] for headings. Default is `true`. + +###### renderHooks.image.enableDefault + +{{< new-in 0.123.0 >}} + +(`bool`) If `true`, enables Hugo's [embedded image render hook]. Default is `false`. + +[embedded image render hook]: /render-hooks/images/#default + +{{% note %}} +The embedded image render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites. + +[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles +{{% /note %}} + +###### renderHooks.link.enableDefault + +{{< new-in 0.123.0 >}} + +(`bool`) If `true`, enables Hugo's [embedded link render hook]. Default is `false`. + +[embedded link render hook]: /render-hooks/links/#default + +{{% note %}} +The embedded link render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites. + +[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles +{{% /note %}} + +###### renderer.hardWraps + +(`bool`) If `true`, Goldmark replaces newline characters within a paragraph with `br` elements. Default is `false`. + +###### renderer.unsafe + +(`bool`) If `true`, Goldmark renders raw HTML mixed within the Markdown. This is unsafe unless the content is under your control. Default is `false`. + +## AsciiDoc + +This is the default configuration for the AsciiDoc renderer: + +{{< code-toggle config=markup.asciidocExt />}} + +### AsciiDoc settings explained + +###### attributes + - (`map`) A map of key-value pairs, each a document attributes,See Asciidoctor’s [attributes]. ++(`map`) A map of key-value pairs, each a document attributes. See Asciidoctor’s [attributes]. + +[attributes]: https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions + +###### backend + +(`string`) The backend output file format. Default is `html5`. + +###### extensions + +(`string array`) An array of enabled extensions, one or more of `asciidoctor-html5s`, `asciidoctor-bibtex`, `asciidoctor-diagram`, `asciidoctor-interdoc-reftext`, `asciidoctor-katex`, `asciidoctor-latex`, `asciidoctor-mathematical`, or `asciidoctor-question`. + +{{% note %}} +To mitigate security risks, entries in the extension array may not contain forward slashes (`/`), backslashes (`\`), or periods. Due to this restriction, extensions must be in Ruby's `$LOAD_PATH`. +{{% /note %}} + +###### failureLevel + +(`string`) The minimum logging level that triggers a non-zero exit code (failure). Default is `fatal`. + +###### noHeaderOrFooter + +(`bool`) If `true`, outputs an embeddable document, which excludes the header, the footer, and everything outside the body of the document. Default is `true`. + +###### preserveTOC + +(`bool`) If `true`, preserves the table of contents (TOC) rendered by Asciidoctor. By default, to make the TOC compatible with existing themes, Hugo removes the TOC rendered by Asciidoctor. To render the TOC, use the [`TableOfContents`] method on a `Page` object in your templates. Default is `false`. + +[`TableOfContents`]: /methods/page/tableofcontents/ + +###### safeMode + +(`string`) The safe mode level, one of `unsafe`, `safe`, `server`, or `secure`. Default is `unsafe`. + +###### sectionNumbers + +(`bool`) If `true`, numbers each section title. Default is `false`. + +###### trace + +(`bool`) If `true`, include backtrace information on errors. Default is `false`. + +###### verbose + +(`bool`)If `true`, verbosely prints processing information and configuration file checks to stderr. Default is `false`. + +###### workingFolderCurrent + +(`bool`) If `true`, sets the working directory to be the same as that of the AsciiDoc file being processed, allowing [includes] to work with relative paths. Set to `true` to render diagrams with the [asciidoctor-diagram] extension. Default is `false`. + +[asciidoctor-diagram]: https://asciidoctor.org/docs/asciidoctor-diagram/ +[includes]: https://docs.asciidoctor.org/asciidoc/latest/syntax-quick-reference/#includes + +### AsciiDoc configuration example + +{{< code-toggle file=hugo >}} +[markup.asciidocExt] + extensions = ["asciidoctor-html5s", "asciidoctor-diagram"] + workingFolderCurrent = true + [markup.asciidocExt.attributes] + my-base-url = "https://example.com/" + my-attribute-name = "my value" +{{< /code-toggle >}} + ++### AsciiDoc syntax highlighting ++ ++Follow the steps below to enable syntax highlighting. ++ ++Step 1 ++: Set the `source-highlighter` attribute in your site configuration. For example: ++ ++{{< code-toggle file=hugo >}} ++[markup.asciidocExt.attributes] ++source-highlighter = 'rouge' ++{{< /code-toggle >}} ++ ++Step 2 ++: Generate the highlighter CSS. For example: ++ ++```text ++rougify style monokai.sublime > assets/css/syntax.css ++``` ++ ++Step 3 ++: In your base template add a link to the CSS file: ++ ++{{< code file=layouts/_default/baseof.html >}} ++ ++ ... ++ {{ with resources.Get "css/syntax.css" }} ++ ++ {{ end }} ++ ... ++ ++{{< /code >}} ++ ++Then add the code to be highlighted to your markup: ++ ++```text ++[#hello,ruby] ++---- ++require 'sinatra' ++ ++get '/hi' do ++ "Hello World!" ++end ++---- ++``` ++ +### AsciiDoc troubleshooting + +Run `hugo --logLevel debug` to examine Hugo's call to the Asciidoctor executable: + +```txt +INFO 2019/12/22 09:08:48 Rendering book-as-pdf.adoc with C:\Ruby26-x64\bin\asciidoctor.bat using asciidoc args [--no-header-footer -r asciidoctor-html5s -b html5s -r asciidoctor-diagram --base-dir D:\prototypes\hugo_asciidoc_ddd\docs -a outdir=D:\prototypes\hugo_asciidoc_ddd\build -] ... +``` + +## Highlight + +This is the default `highlight` configuration. Note that some of these settings can be set per code block, see [Syntax Highlighting](/content-management/syntax-highlighting/). + +{{< code-toggle config=markup.highlight />}} + +For `style`, see these galleries: + +* [Short snippets](https://xyproto.github.io/splash/docs/all.html) +* [Long snippets](https://xyproto.github.io/splash/docs/longer/all.html) + +For CSS, see [Generate Syntax Highlighter CSS](/content-management/syntax-highlighting/#generate-syntax-highlighter-css). + +## Table of contents + +This is the default configuration for the table of contents, applicable to Goldmark and Asciidoctor: + +{{< code-toggle config=markup.tableOfContents />}} + +###### startLevel + +(`int`) Heading levels less than this value will be excluded from the table of contents. For example, to exclude `h1` elements from the table of contents, set this value to `2`. Default is `2`. + +###### endLevel + +(`int`) Heading levels greater than this value will be excluded from the table of contents. For example, to exclude `h4`, `h5`, and `h6` elements from the table of contents, set this value to `3`. Default is `3`. + +###### ordered + +(`bool`) If `true`, generates an ordered list instead of an unordered list. Default is `false`. diff --cc docs/content/en/getting-started/configuration.md index 13474c770,000000000..b0a6cae66 mode 100644,000000..100644 --- a/docs/content/en/getting-started/configuration.md +++ b/docs/content/en/getting-started/configuration.md @@@ -1,960 -1,0 +1,1005 @@@ +--- +title: Configure Hugo +linkTitle: Configuration +description: How to configure your Hugo site. +categories: [getting started,fundamentals] +keywords: [configuration,toml,yaml,json] +menu: + docs: + parent: getting-started + weight: 40 +weight: 40 +toc: true +aliases: [/overview/source-directory/,/overview/configuration/] +--- + +## 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 %}} +With v0.109.0 and earlier the basename of the site configuration file was `config` instead of `hugo`. You can use either, but should transition to the new naming convention when practical. +{{% /note %}} + +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]. + +[TOML]: https://toml.io/en/latest +[YAML]: https://yaml.org/spec/ +[JSON]: https://datatracker.ietf.org/doc/html/rfc7159 +{{% /note %}} + +## Configuration directory + +Instead of a single site configuration file, split your configuration by [environment], root configuration key, and language. For example: + +[environment]: /getting-started/glossary/#environment + +```text +my-project/ +└── config/ + ├── _default/ + │ ├── hugo.toml + │ ├── menus.en.toml + │ ├── menus.de.toml + │ └── params.toml + └── production/ + └── params.toml +``` + +The root configuration keys are `build`, `caches`, `cascade`, `deployment`, `frontmatter`, `imaging`, `languages`, `markup`, `mediatypes`, `menus`, `minify`, `module`, `outputformats`, `outputs`, `params`, `permalinks`, `privacy`, `related`, `security`, `segments`, `server`, `services`, `sitemap`, and `taxonomies`. + +### Omit the root key + +When splitting the configuration by root key, omit the root key in the given file. For example, these are equivalent: + +{{< code-toggle file=hugo >}} +[params] +foo = 'bar' +{{< /code-toggle >}} + +{{< code-toggle file=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: + +[Google tag ID]: https://support.google.com/tagmanager/answer/12326985?hl=en + +{{< code-toggle file=hugo copy=false >}} +[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`. +2. 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. + +2. `config/production/hugo.toml` + + Include this section only: + + {{< code-toggle file=hugo copy=false >}} + [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. + +3. `config/staging/hugo.toml` + + Include this section only: + + {{< code-toggle file=hugo copy=false >}} + [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 from themes + +The configuration 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 />}} + +## All configuration settings + +###### archetypeDir + +(`string`) The directory where Hugo finds archetype files (content templates). Default is `archetypes`. {{% module-mounts-note %}} + +###### assetDir + +(`string`) The directory where Hugo finds asset files used in [Hugo Pipes](/hugo-pipes/). Default is `assets`. {{% module-mounts-note %}} + +###### baseURL + +(`string`) The absolute URL (protocol, host, path, and trailing slash) of your published site (e.g., `https://www.example.org/docs/`). + +###### build + +See [Configure Build](#configure-build). + +###### buildDrafts + +(`bool`) Include drafts when building. Default is `false`. + +###### buildExpired + +(`bool`) Include content already expired. Default is `false`. + +###### buildFuture + +(`bool`) Include content with a future publication date. Default is `false`. + +###### caches + +See [Configure File Caches](#configure-file-caches). + +###### capitalizeListTitles + +{{< new-in 0.123.3 >}} + +(`bool`) Whether to capitalize automatic list titles. Applicable to section, taxonomy, and term pages. Default is `true`. You can change the capitalization style in your site configuration to one of `ap`, `chicago`, `go`, `firstupper`, or `none`. See [details]. + +[details]: /getting-started/configuration/#configure-title-case + +###### cascade + +Pass down default configuration values (front matter) to pages in the content tree. The options in site config is the same as in page front matter, see [Front Matter Cascade](/content-management/front-matter#cascade). + +{{% note %}} +For a website in a single language, define the `[[cascade]]` in [Front Matter](/content-management/front-matter#cascade). For a multilingual website, define the `[[cascade]]` in [Site Config](/getting-started/configuration/#cascade). + +To remain consistent and prevent unexpected behavior, do not mix these strategies. +{{% /note %}} + +###### canonifyURLs + +(`bool`) See [details](/content-management/urls/#canonical-urls) before enabling this feature. Default is `false`. + +###### cleanDestinationDir + +(`bool`) When building, removes files from destination not found in static directories. Default is `false`. + +###### contentDir + +(`string`) The directory from where Hugo reads content files. Default is `content`. {{% module-mounts-note %}} + +###### copyright + +(`string`) Copyright notice for your site, typically displayed in the footer. + +###### dataDir + +(`string`) The directory from where Hugo reads data files. Default is `data`. {{% module-mounts-note %}} + +###### defaultContentLanguage + +(`string`) Content without language indicator will default to this language. Default is `en`. + +###### defaultContentLanguageInSubdir + +(`bool`) Render the default content language in subdir, e.g. `content/en/`. The site root `/` will then redirect to `/en/`. Default is `false`. + +###### disableAliases + +(`bool`) Will disable generation of alias redirects. Note that even if `disableAliases` is set, the aliases themselves are preserved on the page. The motivation with this is to be able to generate 301 redirects in an `.htaccess`, a Netlify `_redirects` file or similar using a custom output format. Default is `false`. + +###### disableHugoGeneratorInject + +(`bool`) Hugo will, by default, inject a generator meta tag in the HTML head on the _home page only_. You can turn it off, but we would really appreciate if you don't, as this is a good way to watch Hugo's popularity on the rise. Default is `false`. + +###### disableKinds + +(`string slice`) Disable rendering of the specified page [kinds], any of `404`, `home`, `page`, `robotstxt`, `rss`, `section`, `sitemap`, `taxonomy`, or `term`. + +[kinds]: /getting-started/glossary/#page-kind + +###### disableLiveReload + +(`bool`) Disable automatic live reloading of browser window. Default is `false`. + +###### disablePathToLower + +(`bool`) Do not convert the url/path to lowercase. Default is `false`. + +###### enableEmoji + +(`bool`) Enable Emoji emoticons support for page content; see the [emoji shortcode quick reference guide](/quick-reference/emojis/). Default is `false`. + +###### enableGitInfo + +(`bool`) Enable `.GitInfo` object for each page (if the Hugo site is versioned by Git). This will then update the `Lastmod` parameter for each page using the last git commit date for that content file. Default is `false`. + +###### enableMissingTranslationPlaceholders + +(`bool`) Show a placeholder instead of the default value or an empty string if a translation is missing. Default is `false`. + +###### enableRobotsTXT + +(`bool`) Enable generation of `robots.txt` file. Default is `false`. + +###### frontmatter + +See [Front matter Configuration](#configure-front-matter). + +###### hasCJKLanguage + +(`bool`) If true, auto-detect Chinese/Japanese/Korean Languages in the content. This will make `.Summary` and `.WordCount` behave correctly for CJK languages. Default is `false`. + +###### imaging + +See [image processing configuration](/content-management/image-processing/#imaging-configuration). + +###### languageCode + +(`string`) A language tag as defined by [RFC 5646](https://datatracker.ietf.org/doc/html/rfc5646). This value is used to populate: + +- The `` element in the embedded [RSS template]({{% eturl rss %}}) +- The `lang` attribute of the `` element in the embedded [alias template]({{% eturl alias %}}) +- The `og:locale` `meta` element in the embedded [Open Graph template]({{% eturl opengraph %}}) + +When present in the root of the configuration, this value is ignored if one or more language keys exists. Please specify this value independently for each language key. + +###### languages + +See [Configure Languages](/content-management/multilingual/#configure-languages). + +###### disableLanguages + +See [Disable a Language](/content-management/multilingual/#disable-a-language) + +###### markup + +See [Configure Markup](/getting-started/configuration-markup). + +###### mediaTypes + +See [Configure Media Types](/templates/output-formats/#media-types). + +###### menus + +See [Menus](/content-management/menus/#define-in-site-configuration). + +###### minify + +See [Configure Minify](#configure-minify). + +###### module + +Module configuration see [module configuration](/hugo-modules/configuration/). + +###### newContentEditor + +(`string`) The editor to use when creating new content. + +###### noChmod + +(`bool`) Don't sync permission mode of files. Default is `false`. + +###### noTimes + +(`bool`) Don't sync modification time of files. Default is `false`. + +###### outputFormats + +See [custom output formats]. + ++###### page ++ ++See [configure page](#configure-page). ++ +###### pagination + +See [configure pagination](/templates/pagination/#configuration). + +###### permalinks + +See [Content Management](/content-management/urls/#permalinks). + +###### pluralizeListTitles + +(`bool`) Whether to pluralize automatic list titles. Applicable to section pages. Default is `true`. + +###### publishDir + +(`string`) The directory to where Hugo will write the final static site (the HTML files etc.). Default is `public`. + +###### refLinksErrorLevel + +(`string`) When using `ref` or `relref` to resolve page links and a link cannot be resolved, it will be logged with this log level. Valid values are `ERROR` (default) or `WARNING`. Any `ERROR` will fail the build (`exit -1`). Default is `ERROR`. + +###### refLinksNotFoundURL + +(`string`) URL to be used as a placeholder when a page reference cannot be found in `ref` or `relref`. Is used as-is. + +###### related + +See [Related Content](/content-management/related/#configure-related-content). + +###### relativeURLs + +(`bool`) See [details](/content-management/urls/#relative-urls) before enabling this feature. Default is `false`. + +###### renderSegments + +{{< new-in 0.124.0 >}} + +(`string slice`) A list of segments to render. If not set, everything will be rendered. This is more commonly set in a CLI flag, e.g. `hugo --renderSegments segment1,segment2`. The segment names must match the names in the [segments](#configure-segments) configuration. + +###### removePathAccents + +(`bool`) Removes [non-spacing marks](https://www.compart.com/en/unicode/category/Mn) from [composite characters](https://en.wikipedia.org/wiki/Precomposed_character) in content paths. Default is `false`. + +```text +content/post/hügó.md → https://example.org/post/hugo/ +``` + +###### sectionPagesMenu + +See [Menus](/content-management/menus/#define-automatically). + +###### security + +See [Security Policy](/about/security/#security-policy). + +###### segments + +See [Segments](#configure-segments). + +###### sitemap + +Default [sitemap configuration](/templates/sitemap/#configuration). + +###### summaryLength + +(`int`) Applicable to automatic summaries, the approximate number of words to render when calling the [`Summary`] method on a `Page` object. Default is `70`. + +[`Summary`]: /methods/page/summary/ + +###### taxonomies + +See [Configure Taxonomies](/content-management/taxonomies#configure-taxonomies). + +###### theme + +See [module configuration](/hugo-modules/configuration/#module-configuration-imports) for how to import a theme. + +###### themesDir + +(`string`) The directory where Hugo reads the themes from. Default is `themes`. + +###### timeout + +(`string`) Timeout for generating page contents, specified as a [duration](https://pkg.go.dev/time#Duration) or in seconds. *Note:* this is used to bail out of recursive content generation. You might need to raise this limit if your pages are slow to generate (e.g., because they require large image processing or depend on remote contents). Default is `30s`. + +###### timeZone + +(`string`) The time zone (or location), e.g. `Europe/Oslo`, used to parse front matter dates without such information and in the [`time`] function. The list of valid values may be system dependent, but should include `UTC`, `Local`, and any location in the [IANA Time Zone database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). + +###### title + +(`string`) Site title. + +###### titleCaseStyle + +(`string`) Default is `ap`. See [Configure Title Case](#configure-title-case). + +###### uglyURLs + +(`bool`) When enabled, creates URL of the form `/filename.html` instead of `/filename/`. Default is `false`. + +###### watch + +(`bool`) Watch filesystem for changes and recreate as needed. Default is `false`. + +{{% note %}} +If you are developing your site on a \*nix machine, here is a handy shortcut for finding a configuration option from the command line: +```txt +cd ~/sites/yourhugosite +hugo config | grep emoji +``` + +which shows output like + +```txt +enableemoji: true +``` +{{% /note %}} + ++## Configure page ++ ++{{< new-in 0.133.0 >}} ++ ++These methods on a `Page` object navigate to the next or previous page within a page collection, relative to the current page: ++ ++- [Next](/methods/page/next/) ++- [NextInSection](/methods/page/nextinsection/) ++- [Prev](/methods/page/prev/) ++- [PrevInSection](/methods/page/previnsection/) ++ ++Hugo determines the _next_ and _previous_ page by sorting a page collection according to this sorting hierarchy: ++ ++Field|Precedence|Sort direction ++:--|:--|:-- ++[`weight`]|1|descending ++[`date`]|2|descending ++[`linkTitle`]|3|descending ++[`path`]|4|descending ++ ++[`date`]: /methods/page/date/ ++[`weight`]: /methods/page/weight/ ++[`linkTitle`]: /methods/page/linktitle/ ++[`path`]: /methods/page/path/ ++ ++The sort direction in the table above corresponds to these default site configuration values: ++ ++{{< code-toggle config=page />}} ++ ++To sort all fields in ascending order: ++ ++{{< code-toggle file=hugo >}} ++[page] ++ nextPrevInSectionSortOrder = 'asc' ++ nextPrevSortOrder = 'asc' ++{{< /code-toggle >}} ++ ++{{% note %}} ++These settings do not apply to the [`Next`] or [`Prev`] methods on a `Pages` object. ++ ++[`Next`]: /methods/pages/next ++[`Prev`]: /methods/pages/next ++{{% /note %}} ++ +## Configure build + +The `build` configuration section contains global build-related configuration options. + +{{< code-toggle config=build />}} + +buildStats {{< new-in 0.115.1 >}} +: When enabled, creates a `hugo_stats.json` file in the root of your project. This file contains arrays of the `class` attributes, `id` attributes, and tags of every HTML element within your published site. Use this file as data source when [removing unused CSS] from your site. This process is also known as pruning, purging, or tree shaking. + +[removing unused CSS]: /hugo-pipes/postprocess/#css-purging-with-postcss + +Exclude `class` attributes, `id` attributes, or tags from `hugo_stats.json` with the `disableClasses`, `disableIDs`, and `disableTags` keys. + +{{% note %}} +With v0.115.0 and earlier this feature was enabled by setting `writeStats` to `true`. Although still functional, the `writeStats` key will be deprecated in a future release. + +Given that CSS purging is typically limited to production builds, place the `buildStats` object below [config/production]. + +[config/production]: /getting-started/configuration/#configuration-directory + +Built for speed, there may be "false positive" detections (e.g., HTML elements that are not HTML elements) while parsing the published site. These "false positives" are infrequent and inconsequential. +{{% /note %}} + +Due to the nature of partial server builds, new HTML entities are added while the server is running, but old values will not be removed until you restart the server or run a regular `hugo` build. + +cachebusters +: See [Configure Cache Busters](#configure-cache-busters) + +noJSConfigInAssets +: Turn off writing a `jsconfig.json` into your `/assets` folder with mapping of imports from running [js.Build](/hugo-pipes/js). This file is intended to help with intellisense/navigation inside code editors such as [VS Code](https://code.visualstudio.com/). Note that if you do not use `js.Build`, no file will be written. + +useResourceCacheWhen +: When to use the cached resources in `/resources/_gen` for PostCSS and ToCSS. Valid values are `never`, `always` and `fallback`. The last value means that the cache will be tried if PostCSS/extended version is not available. + +## Configure cache busters + +{{< new-in 0.112.0 >}} + +The `build.cachebusters` configuration option was added to support development using Tailwind 3.x's JIT compiler where a `build` configuration may look like this: + +{{< code-toggle file=hugo >}} +[build] + [build.buildStats] + enable = true + [[build.cachebusters]] + source = "assets/watching/hugo_stats\\.json" + target = "styles\\.css" + [[build.cachebusters]] + source = "(postcss|tailwind)\\.config\\.js" + target = "css" + [[build.cachebusters]] + source = "assets/.*\\.(js|ts|jsx|tsx)" + target = "js" + [[build.cachebusters]] + source = "assets/.*\\.(.*)$" + target = "$1" +{{< /code-toggle >}} + +When `buildStats` {{< new-in 0.115.1 >}} is enabled, Hugo writes a `hugo_stats.json` file on each build with HTML classes etc. that's used in the rendered output. Changes to this file will trigger a rebuild of the `styles.css` file. You also need to add `hugo_stats.json` to Hugo's server watcher. See [Hugo Starter Tailwind Basic](https://github.com/bep/hugo-starter-tailwind-basic) for a running example. + +source +: A regexp matching file(s) relative to one of the virtual component directories in Hugo, typically `assets/...`. + +target +: A regexp matching the keys in the resource cache that should be expired when `source` changes. You can use the matching regexp groups from `source` in the expression, e.g. `$1`. + +## Configure server + +This is only relevant when running `hugo server`, and it allows to set HTTP headers during development, which allows you to test out your Content Security Policy and similar. The configuration format matches [Netlify's](https://docs.netlify.com/routing/headers/#syntax-for-the-netlify-configuration-file) with slightly more powerful [Glob matching](https://github.com/gobwas/glob): + +{{< code-toggle file=hugo >}} +[server] +[[server.headers]] +for = "/**" + +[server.headers.values] +X-Frame-Options = "DENY" +X-XSS-Protection = "1; mode=block" +X-Content-Type-Options = "nosniff" +Referrer-Policy = "strict-origin-when-cross-origin" +Content-Security-Policy = "script-src localhost:1313" +{{< /code-toggle >}} + +Since this is "development only", it may make sense to put it below the `development` environment: + +{{< code-toggle file=config/development/server >}} +[[headers]] +for = "/**" + +[headers.values] +X-Frame-Options = "DENY" +X-XSS-Protection = "1; mode=block" +X-Content-Type-Options = "nosniff" +Referrer-Policy = "strict-origin-when-cross-origin" +Content-Security-Policy = "script-src localhost:1313" +{{< /code-toggle >}} + +You can also specify simple redirects rules for the server. The syntax is again similar to Netlify's. + +Note that a `status` code of 200 will trigger a [URL rewrite](https://docs.netlify.com/routing/redirects/rewrites-proxies/), which is what you want in SPA situations, e.g: + +{{< code-toggle file=config/development/server >}} +[[redirects]] +from = "/myspa/**" +to = "/myspa/" +status = 200 +force = false +{{< /code-toggle >}} + +Setting `force=true` will make a redirect even if there is existing content in the path. Note that before Hugo 0.76 `force` was the default behavior, but this is inline with how Netlify does it. + +## 404 server error page {#_404-server-error-page} + - {{< new-in 0.103.0 >}} - +Hugo will, by default, render all 404 errors when running `hugo server` with the `404.html` template. Note that if you have already added one or more redirects to your [server configuration](#configure-server), you need to add the 404 redirect explicitly, e.g: + +{{< code-toggle file=config/development/server >}} +[[redirects]] +from = "/**" +to = "/404.html" +status = 404 +{{< /code-toggle >}} + +With a multilingual site, define the redirect for the default content language last: + +{{< code-toggle file=config/development/server >}} +defaultContentLanguage = 'en' +defaultContentLanguageInSubdir = false +[[redirects]] +from = '/fr/**' +to = '/fr/404.html' +status = 404 + +[[redirects]] # Default language must be last. +from = '/**' +to = '/404.html' +status = 404 +{{< /code-toggle >}} + +If you are serving the default content language from a subdirectory: + +{{< code-toggle file=config/development/server >}} +defaultContentLanguage = 'en' +defaultContentLanguageInSubdir = true +[[redirects]] +from = '/fr/**' +to = '/fr/404.html' +status = 404 + +[[redirects]] # Default language must be last. +from = '/**' +to = '/en/404.html' +status = 404 +{{< /code-toggle >}} + + +## Configure title case + +By default, Hugo follows the capitalization rules published in the [Associated Press Stylebook] when creating automatic section titles, and when transforming strings with the [`strings.Title`] function. + +Change this behavior by setting `titleCaseStyle` in your site configuration to any of the values below: + +ap +: Use the capitalization rules published in the [Associated Press Stylebook]. + +chicago +: Use the capitalization rules published in the [Chicago Manual of Style]. + +go +: Capitalize the first letter of every word. + +firstupper +: Capitalize the first letter of the first word. + +none +: Disable transformation of automatic section titles, and disable the transformation performed by the `strings.Title` function. This is useful if you would prefer to manually capitalize section titles as needed, and to bypass opinionated theme usage of the `strings.Title` function. + +[`strings.Title`]: /functions/strings/title/ +[Associated Press Stylebook]: https://www.apstylebook.com/ +[Chicago Manual of Style]: https://www.chicagomanualofstyle.org/home.html +[site configuration]: /getting-started/configuration/#configure-title-case + +## Configuration environment variables + +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_ENVIRONMENT +: (`string`) Overrides the default [environment], typically one of `development`, `staging`, or `production`. + +[environment]: /getting-started/glossary/#environment + +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`. + +{{< new-in 0.123.0 >}} + +HUGO_MEMORYLIMIT +: (`int`) The maximum amount of system memory, in gigabytes, that Hugo can use while rendering your site. Default is 25% of total system memory. + +HUGO_NUMWORKERMULTIPLIER +: (`int`) The number of workers used in parallel processing. Default is the number of logical CPUs. + +## Configure with environment variables + +In addition to the 3 configuration options already mentioned, configuration key-values can be defined through operating system environment variables. + +For example, the following command will effectively set a website's title on Unix-like systems: + +```txt +$ env HUGO_TITLE="Some Title" hugo +``` + +This is really useful if you use a service such as Netlify to deploy your site. Look at the Hugo docs [Netlify configuration file](https://github.com/gohugoio/hugoDocs/blob/master/netlify.toml) for an example. + +{{% note %}} +Names must be prefixed with `HUGO_` and the configuration key must be set in uppercase when setting operating system environment variables. + +To set configuration parameters, prefix the name with `HUGO_PARAMS_` +{{% /note %}} + +If you are using snake_cased variable names, the above will not work. Hugo determines the delimiter to use by the first character after `HUGO`. This allows you to define environment variables on the form `HUGOxPARAMSxAPI_KEY=abcdefgh`, using any [allowed](https://stackoverflow.com/questions/2821043/allowed-characters-in-linux-environment-variable-names#:~:text=So%20names%20may%20contain%20any,not%20begin%20with%20a%20digit.) delimiter. + +## Ignore content and data files when rendering + +{{% note %}} +This works, but we recommend you use the newer and more powerful [includeFiles and excludeFiles](/hugo-modules/configuration/#module-configuration-mounts) mount options. +{{% /note %}} + +To exclude specific files from the `content`, `data`, and `i18n` directories when rendering your site, set `ignoreFiles` to one or more regular expressions to match against the absolute file path. + +To ignore files ending with `.foo` or `.boo`: + +{{< code-toggle file=hugo >}} +ignoreFiles = ['\.foo$', '\.boo$'] +{{< /code-toggle >}} + +To ignore a file using the absolute file path: + +{{< code-toggle file=hugo >}} +ignoreFiles = ['^/home/user/project/content/test\.md$'] +{{< /code-toggle >}} + +## Configure front matter + +### Configure dates + +Dates are important in Hugo, and you can configure how Hugo assigns dates to your content pages. You do this by adding a `frontmatter` section to your `hugo.toml`. + +The default configuration is: + +{{< code-toggle config=frontmatter />}} + +If you, as an example, have a non-standard date parameter in some of your content, you can override the setting for `date`: + +{{< code-toggle file=hugo >}} +[frontmatter] +date = ["myDate", ":default"] +{{< /code-toggle >}} + +The `:default` is a shortcut to the default settings. The above will set `.Date` to the date value in `myDate` if present, if not we will look in `date`,`publishDate`, `lastmod` and pick the first valid date. + +In the list to the right, values starting with ":" are date handlers with a special meaning (see below). The others are just names of date parameters (case insensitive) in your front matter configuration. Also note that Hugo have some built-in aliases to the above: `lastmod` => `modified`, `publishDate` => `pubdate`, `published` and `expiryDate` => `unpublishdate`. With that, as an example, using `pubDate` as a date in front matter, will, by default, be assigned to `.PublishDate`. + +The special date handlers are: + +`:fileModTime` +: Fetches the date from the content file's last modification timestamp. + +An example: + +{{< code-toggle file=hugo >}} +[frontmatter] +lastmod = ["lastmod", ":fileModTime", ":default"] +{{< /code-toggle >}} + +The above will try first to extract the value for `.Lastmod` starting with the `lastmod` front matter parameter, then the content file's modification timestamp. The last, `:default` should not be needed here, but Hugo will finally look for a valid date in `:git`, `date` and then `publishDate`. + +`:filename` +: Fetches the date from the content file's file name. For example, `2018-02-22-mypage.md` will extract the date `2018-02-22`. Also, if `slug` is not set, `mypage` will be used as the value for `.Slug`. + +An example: + +{{< code-toggle file=hugo >}} +[frontmatter] +date = [":filename", ":default"] +{{< /code-toggle >}} + +The above will try first to extract the value for `.Date` from the file name, then it will look in front matter parameters `date`, `publishDate` and lastly `lastmod`. + +`:git` +: This is the Git author date for the last revision of this content file. This will only be set if `--enableGitInfo` is set or `enableGitInfo = true` is set in site configuration. + +## Configure minify + +See the [tdewolff/minify] project page for details. + +[tdewolff/minify]: https://github.com/tdewolff/minify + +Default configuration: + +{{< code-toggle config=minify />}} + +## Configure file caches + +Since Hugo 0.52 you can configure more than just the `cacheDir`. This is the default configuration: + +{{< code-toggle config=caches />}} + +You can override any of these cache settings in your own `hugo.toml`. + +### The keywords explained + +cacheDir +: (`string`) See [Configure cacheDir](#configure-cachedir). + +project +: (`string`) The base directory name of the current Hugo project. This means that, in its default setting, every project will have separated file caches, which means that when you do `hugo --gc` you will not touch files related to other Hugo projects running on the same PC. + +resourceDir +: (`string`) This is the value of the `resourceDir` configuration option. + +maxAge +: (`string`) This is the duration before a cache entry will be evicted, -1 means forever and 0 effectively turns that particular cache off. Uses Go's `time.Duration`, so valid values are `"10s"` (10 seconds), `"10m"` (10 minutes) and `"10h"` (10 hours). + +dir +: (`string`) The absolute path to where the files for this cache will be stored. Allowed starting placeholders are `:cacheDir` and `:resourceDir` (see above). + +## Configure cacheDir + +This is the directory where Hugo by default will store its file caches. See [Configure File Caches](#configure-file-caches). + +This can be set using the `cacheDir` config option or via the OS environment variable `HUGO_CACHEDIR`. + +If this is not set, Hugo will use, in order of preference: + +1. If running on Netlify: `/opt/build/cache/hugo_cache/`. This means that if you run your builds on Netlify, all caches configured with `:cacheDir` will be saved and restored on the next build. For other CI vendors, please read their documentation. For an CircleCI example, see [this configuration](https://github.com/bep/hugo-sass-test/blob/6c3960a8f4b90e8938228688bc49bdcdd6b2d99e/.circleci/config.yml). +1. In a `hugo_cache` directory below the OS user cache directory as defined by Go's [os.UserCacheDir](https://pkg.go.dev/os#UserCacheDir). On Unix systems, this is `$XDG_CACHE_HOME` as specified by [basedir-spec-latest](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) if non-empty, else `$HOME/.cache`. On MacOS, this is `$HOME/Library/Caches`. On Windows, this is`%LocalAppData%`. On Plan 9, this is `$home/lib/cache`. {{< new-in 0.116.0 >}} +1. In a `hugo_cache_$USER` directory below the OS temp dir. + +If you want to know the current value of `cacheDir`, you can run `hugo config`, e.g: `hugo config | grep cachedir`. + +[`time`]: /functions/time/astime/ +[`.Site.Params`]: /method/site/params/ +[directory structure]: /getting-started/directory-structure/ +[lookup order]: /templates/lookup-order/ +[custom output formats]: /templates/output-formats/ +[templates]: /templates/ +[static-files]: /content-management/static-files/ + + +## Configure HTTP cache + +{{< new-in 0.127.0 >}} + +Note that this configuration is currently only relevant when using the [resources.GetRemote] function. + +The caching in Hugo is layered: + +```goat {.w-40} + .-----------. +| dynacache | + '-----+-----' + | + v + .----------. +| HTTP cache | + '-----+----' + | + v + .----------. +| file cache | + '-----+----' +``` + +Dynacache +: A in memory LRU cache that gets evicted on changes, [Cache Buster](#configure-cache-busters) matches and in low memory situations. + +HTTP Cache +: Enables HTTP cache behavior (RFC 9111) for remote resources. This works best for resources with properly set up HTTP cache headers. The HTTP cache uses the [file cache] to store and serve cached resources. + +File Cache +: See [file cache]. + +The default HTTP cache disables everything: + +{{< code-toggle config=HTTPCache />}} + +caching +: Enabled RFC 9111 cache behavior _for_ a configured set of resources. Stale resources will be refreshed from the [file cache] even if their configured TTL isn't reached. + +polling +: Enables polling _for_ a set of resources. Note that you can enable polling for resources even if HTTP caching is disabled. This setting is only used when in watch mode (e.g. `hugo server`). When a changed resource is detected, that change triggers a rebuild of pages using that resource. + +[resources.GetRemote]: /functions/resources/getremote/ +[file cache]: #configure-file-caches + +## Configure segments + +{{< new-in 0.124.0 >}} + +{{% note %}} +The `segments` configuration is currently only used to configure partitioned rendering. +This feature is only about what gets rendered when, Hugo's entire object graph (sites and pages) is +always available. +{{% /note %}} + +* Each segment consists of zero or more `exclude` filters and zero or more `include` filters. +* Each filter consists of one or more field Glob matchers. +* Each filter in a section (`exclude` or `include`) is ORed together, each matcher in a filter is ANDed together. + +The fields that can be used in the filters are: + +path +: The logical page [path]. + +lang +: The [page language]. + +kind +: The [kind] of the page. + +output +: The [output format] of the page. + +It is recommended to put coarse grained filters (e.g. for language and output format) in the excludes section, e.g.: + - +{{< code-toggle file=hugo >}} +[segments.segment1] + [[segments.segment1.excludes]] + lang = "n*" + [[segments.segment1.excludes]] + lang = "en" + output = "rss" + [[segments.segment1.includes]] + kind = "{home,term,taxonomy}" + [[segments.segment1.includes]] + path = "{/docs,/docs/**}" +{{< /code-toggle >}} + +With the above you can render only the pages in `segment1` by configuring the [renderSegments](#rendersegments) or setting the `--renderSegments` flag: + +```bash +hugo --renderSegments segment1 +``` + +Multiple segments can be configured, and the `--renderSegments` flag can take a comma separated list of segments. + +Some use cases for this feature: + +* Splitting builds of big sites. +* Enable faster builds during development by only rendering a subset of the site. +* Partial rebuilds, e.g. render the home page and the "news section" every hour, render the entire site once a week. +* Render only e.g. the JSON output format to push to e.g. a search index. + +[path]: /methods/page/path/ +[page language]: /methods/page/language/ +[kind]: /getting-started/glossary/#page-kind +[output format]: /getting-started/glossary/#output-format +[type]: /getting-started/glossary/#content-type diff --cc docs/content/en/methods/page/Next.md index 57fc1f2f8,000000000..ff0525700 mode 100644,000000..100644 --- a/docs/content/en/methods/page/Next.md +++ b/docs/content/en/methods/page/Next.md @@@ -1,53 -1,0 +1,17 @@@ +--- +title: Next - description: Returns the next page in a global page collection, relative to the given page. ++description: Returns the next page in a site's collection of regular pages, relative to the current page. +categories: [] +keywords: [] +action: + related: + - methods/page/Prev + - methods/page/NextInSection + - methods/page/PrevInSection + - methods/pages/Next + - methods/pages/Prev + returnType: page.Page + signatures: [PAGE.Next] - toc: true +--- + - The behavior of the `Prev` and `Next` methods on a `Page` object is probably the reverse of what you expect. - - With this content structure: - - ```text - content/ - ├── pages/ - │ ├── _index.md - │ ├── page-1.md <-- front matter: weight = 10 - │ ├── page-2.md <-- front matter: weight = 20 - │ └── page-3.md <-- front matter: weight = 30 - └── _index.md - ``` - - When you visit page-2: - - - The `Prev` method points to page-3 - - The `Next` method points to page-1 - - {{% note %}} - Use the opposite label in your navigation links as shown in the example below. - {{% /note %}} - - ```go-html-template - {{ with .Next }} - Prev - {{ end }} - - {{ with .Prev }} - Next - {{ end }} - ``` - - ## Compare to Pages methods - - {{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}} ++{{% include "methods/page/_common/next-and-prev.md" %}} diff --cc docs/content/en/methods/page/NextInSection.md index 59a35d03d,000000000..640e9b44a mode 100644,000000..100644 --- a/docs/content/en/methods/page/NextInSection.md +++ b/docs/content/en/methods/page/NextInSection.md @@@ -1,71 -1,0 +1,15 @@@ +--- +title: NextInSection - description: Returns the next page within a section, relative to the given page. ++description: Returns the next regular page in a section, relative to the given page. +categories: [] +keywords: [] +action: + related: + - methods/page/PrevInSection - - methods/page/Next - - methods/page/Prev + - methods/pages/Next + - methods/pages/Prev + returnType: page.Page + signatures: [PAGE.NextInSection] +--- + - The behavior of the `PrevInSection` and `NextInSection` methods on a `Page` object is probably the reverse of what you expect. - - With this content structure: - - ```text - content/ - ├── books/ - │ ├── _index.md - │ ├── book-1.md - │ ├── book-2.md - │ └── book-3.md - ├── films/ - │ ├── _index.md - │ ├── film-1.md - │ ├── film-2.md - │ └── film-3.md - └── _index.md - ``` - - When you visit book-2: - - - The `PrevInSection` method points to book-3 - - The `NextInSection` method points to book-1 - - {{% note %}} - Use the opposite label in your navigation links as shown in the example below. - {{% /note %}} - - ```go-html-template - {{ with .NextInSection }} - Previous in section - {{ end }} - - {{ with .PrevInSection }} - Next in section - {{ end }} - ``` - - {{% note %}} - The navigation sort order may be different than the page collection sort order. - {{% /note %}} - - With the `PrevInSection` and `NextInSection` methods, the navigation sort order is fixed, using Hugo’s default sort order. In order of precedence: - - 1. Page [weight] - 2. Page [date] (descending) - 3. Page [linkTitle], falling back to page [title] - 4. Page file path if the page is backed by a file - - For example, with a page collection sorted by title, the navigation sort order will use Hugo’s default sort order. This is probably not what you want or expect. For this reason, the Next and Prev methods on a Pages object are generally a better choice. - - [date]: /methods/page/date/ - [weight]: /methods/page/weight/ - [linkTitle]: /methods/page/linktitle/ - [title]: /methods/page/title/ ++{{% include "methods/page/_common/nextinsection-and-previnsection.md" %}} diff --cc docs/content/en/methods/page/Prev.md index b1a503af5,000000000..d28b50265 mode 100644,000000..100644 --- a/docs/content/en/methods/page/Prev.md +++ b/docs/content/en/methods/page/Prev.md @@@ -1,53 -1,0 +1,17 @@@ +--- +title: Prev - description: Returns the previous page in a global page collection, relative to the given page. ++description: Returns the previous page in a site's collection of regular pages, relative to the current page. +categories: [] +keywords: [] +action: + related: + - methods/page/Next - - methods/page/PrevInSection + - methods/page/NextInSection - - methods/pages/Prev ++ - methods/page/PrevInSection + - methods/pages/Next ++ - methods/pages/Prev + returnType: page.Page + signatures: [PAGE.Prev] - toc: true +--- + - The behavior of the `Prev` and `Next` methods on a `Page` object is probably the reverse of what you expect. - - With this content structure: - - ```text - content/ - ├── pages/ - │ ├── _index.md - │ ├── page-1.md <-- front matter: weight = 10 - │ ├── page-2.md <-- front matter: weight = 20 - │ └── page-3.md <-- front matter: weight = 30 - └── _index.md - ``` - - When you visit page-2: - - - The `Prev` method points to page-3 - - The `Next` method points to page-1 - - {{% note %}} - Use the opposite label in your navigation links as shown in the example below. - {{% /note %}} - - ```go-html-template - {{ with .Next }} - Prev - {{ end }} - - {{ with .Prev }} - Next - {{ end }} - ``` - - ## Compare to Pages methods - - {{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}} ++{{% include "methods/page/_common/next-and-prev.md" %}} diff --cc docs/content/en/methods/page/PrevInSection.md index e6daf66c4,000000000..aaafb367e mode 100644,000000..100644 --- a/docs/content/en/methods/page/PrevInSection.md +++ b/docs/content/en/methods/page/PrevInSection.md @@@ -1,72 -1,0 +1,15 @@@ +--- +title: PrevInSection - description: Returns the previous page within a section, relative to the given page. ++description: Returns the previous regular page in a section, relative to the given page. +categories: [] +keywords: [] +action: + related: + - methods/page/NextInSection - - methods/page/Next + - methods/pages/Next - - methods/page/Prev + - methods/pages/Prev + returnType: page.Page + signatures: [PAGE.PrevInSection] +--- + - - The behavior of the `PrevInSection` and `NextInSection` methods on a `Page` object is probably the reverse of what you expect. - - With this content structure: - - ```text - content/ - ├── books/ - │ ├── _index.md - │ ├── book-1.md - │ ├── book-2.md - │ └── book-3.md - ├── films/ - │ ├── _index.md - │ ├── film-1.md - │ ├── film-2.md - │ └── film-3.md - └── _index.md - ``` - - When you visit book-2: - - - The `PrevInSection` method points to book-3 - - The `NextInSection` method points to book-1 - - {{% note %}} - Use the opposite label in your navigation links as shown in the example below. - {{% /note %}} - - ```go-html-template - {{ with .NextInSection }} - Previous in section - {{ end }} - - {{ with .PrevInSection }} - Next in section - {{ end }} - ``` - - {{% note %}} - The navigation sort order may be different than the page collection sort order. - {{% /note %}} - - With the `PrevInSection` and `NextInSection` methods, the navigation sort order is fixed, using Hugo’s default sort order. In order of precedence: - - 1. Page [weight] - 2. Page [date] (descending) - 3. Page [linkTitle], falling back to page [title] - 4. Page file path if the page is backed by a file - - For example, with a page collection sorted by title, the navigation sort order will use Hugo’s default sort order. This is probably not what you want or expect. For this reason, the Next and Prev methods on a Pages object are generally a better choice. - - [date]: /methods/page/date/ - [weight]: /methods/page/weight/ - [linkTitle]: /methods/page/linktitle/ - [title]: /methods/page/title/ ++{{% include "methods/page/_common/nextinsection-and-previnsection.md" %}} diff --cc docs/content/en/methods/page/_common/next-and-prev.md index 000000000,000000000..0d1436e11 new file mode 100644 --- /dev/null +++ b/docs/content/en/methods/page/_common/next-and-prev.md @@@ -1,0 -1,0 +1,60 @@@ ++--- ++# Do not remove front matter. ++--- ++ ++Hugo determines the _next_ and _previous_ page by sorting the site's collection of regular pages according to this sorting hierarchy: ++ ++Field|Precedence|Sort direction ++:--|:--|:-- ++[`weight`]|1|descending ++[`date`]|2|descending ++[`linkTitle`]|3|descending ++[`path`]|4|descending ++ ++[`date`]: /methods/page/date/ ++[`weight`]: /methods/page/weight/ ++[`linkTitle`]: /methods/page/linktitle/ ++[`path`]: /methods/page/path/ ++ ++The sorted page collection used to determine the _next_ and _previous_ page is independent of other page collections, which may lead to unexpected behavior. ++ ++For example, with this content structure: ++ ++```text ++content/ ++├── pages/ ++│ ├── _index.md ++│ ├── page-1.md <-- front matter: weight = 10 ++│ ├── page-2.md <-- front matter: weight = 20 ++│ └── page-3.md <-- front matter: weight = 30 ++└── _index.md ++``` ++ ++And these templates: ++ ++{{< code file=layouts/_default/list.html >}} ++{{ range .Pages.ByWeight }} ++

{{ .LinkTitle }}

++{{ end }} ++{{< /code >}} ++ ++{{< code file=layouts/_default/single.html >}} ++{{ with .Prev }} ++ Previous ++{{ end }} ++ ++{{ with .Next }} ++ Next ++{{ end }} ++{{< /code >}} ++ ++When you visit page-2: ++ ++- The `Prev` method points to page-3 ++- The `Next` method points to page-1 ++ ++To reverse the meaning of _next_ and _previous_ you can change the sort direction in your [site configuration], or use the [`Next`] and [`Prev`] methods on a `Pages` object for more flexibility. ++ ++[site configuration]: getting-started/configuration/#configure-page ++[`Next`]: /methods/pages/prev ++[`Prev`]: /methods/pages/prev diff --cc docs/content/en/methods/page/_common/nextinsection-and-previnsection.md index 000000000,000000000..6c558b69e new file mode 100644 --- /dev/null +++ b/docs/content/en/methods/page/_common/nextinsection-and-previnsection.md @@@ -1,0 -1,0 +1,78 @@@ ++--- ++# Do not remove front matter. ++--- ++ ++Hugo determines the _next_ and _previous_ page by sorting the current section's regular pages according to this sorting hierarchy: ++ ++Field|Precedence|Sort direction ++:--|:--|:-- ++[`weight`]|1|descending ++[`date`]|2|descending ++[`linkTitle`]|3|descending ++[`path`]|4|descending ++ ++[`date`]: /methods/page/date/ ++[`weight`]: /methods/page/weight/ ++[`linkTitle`]: /methods/page/linktitle/ ++[`path`]: /methods/page/path/ ++ ++The sorted page collection used to determine the _next_ and _previous_ page is independent of other page collections, which may lead to unexpected behavior. ++ ++For example, with this content structure: ++ ++```text ++content/ ++├── pages/ ++│ ├── _index.md ++│ ├── page-1.md <-- front matter: weight = 10 ++│ ├── page-2.md <-- front matter: weight = 20 ++│ └── page-3.md <-- front matter: weight = 30 ++└── _index.md ++``` ++ ++And these templates: ++ ++{{< code file=layouts/_default/list.html >}} ++{{ range .Pages.ByWeight }} ++

{{ .LinkTitle }}

++{{ end }} ++{{< /code >}} ++ ++{{< code file=layouts/_default/single.html >}} ++{{ with .PrevInSection }} ++ Previous ++{{ end }} ++ ++{{ with .NextInSection }} ++ Next ++{{ end }} ++{{< /code >}} ++ ++When you visit page-2: ++ ++- The `PrevInSection` method points to page-3 ++- The `NextInSection` method points to page-1 ++ ++To reverse the meaning of _next_ and _previous_ you can change the sort direction in your [site configuration], or use the [`Next`] and [`Prev`] methods on a `Pages` object for more flexibility. ++ ++[site configuration]: getting-started/configuration/#configure-page ++[`Next`]: /methods/pages/prev ++[`Prev`]: /methods/pages/prev ++ ++## Example ++ ++Code defensively by checking for page existence: ++ ++```go-html-template ++{{ with .PrevInSection }} ++ Previous ++{{ end }} ++ ++{{ with .NextInSection }} ++ Next ++{{ end }} ++``` ++ ++## Alternative ++ ++Use the [`Next`] and [`Prev`] methods on a `Pages` object for more flexibility. diff --cc docs/content/en/methods/pages/Next.md index b7284609f,000000000..dcf1231ac mode 100644,000000..100644 --- a/docs/content/en/methods/pages/Next.md +++ b/docs/content/en/methods/pages/Next.md @@@ -1,55 -1,0 +1,17 @@@ +--- +title: Next - description: Returns the next page in a local page collection, relative to the given page. ++description: Returns the next page in a page collection, relative to the given page. +categories: [] +keywords: [] +action: + related: + - methods/pages/Prev + - methods/page/Next - - methods/page/NextInSection + - methods/page/Prev ++ - methods/page/NextInSection + - methods/page/PrevInSection + returnType: page.Page + signatures: [PAGES.Next PAGE] - toc: true +--- + - The behavior of the `Prev` and `Next` methods on a `Pages` objects is probably the reverse of what you expect. - - With this content structure and the page collection sorted by weight in ascending order: - - ```text - content/ - ├── pages/ - │ ├── _index.md - │ ├── page-1.md <-- front matter: weight = 10 - │ ├── page-2.md <-- front matter: weight = 20 - │ └── page-3.md <-- front matter: weight = 30 - └── _index.md - ``` - - When you visit page-2: - - - The `Prev` method points to page-3 - - The `Next` method points to page-1 - - {{% note %}} - Use the opposite label in your navigation links as shown in the example below. - {{% /note %}} - - ```go-html-template - {{ $pages := where .Site.RegularPages.ByWeight "Section" "pages" }} - - {{ with $pages.Next . }} - Previous - {{ end }} - - {{ with $pages.Prev . }} - Next - {{ end }} - ``` - - ## Compare to Page methods - - {{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}} ++{{% include "methods/pages/_common/next-and-prev.md" %}} diff --cc docs/content/en/methods/pages/Prev.md index b9ef27a45,000000000..2d8738521 mode 100644,000000..100644 --- a/docs/content/en/methods/pages/Prev.md +++ b/docs/content/en/methods/pages/Prev.md @@@ -1,55 -1,0 +1,17 @@@ +--- +title: Prev - description: Returns the previous page in a local page collection, relative to the given page. ++description: Returns the previous page in a page collection, relative to the given page. +categories: [] +keywords: [] +action: + related: + - methods/pages/Next + - methods/page/Next - - methods/page/NextInSection + - methods/page/Prev ++ - methods/page/NextInSection + - methods/page/PrevInSection + returnType: page.Pages + signatures: [PAGES.Prev PAGE] - toc: true +--- + - The behavior of the `Prev` and `Next` methods on a `Pages` objects is probably the reverse of what you expect. - - With this content structure and the page collection sorted by weight in ascending order: - - ```text - content/ - ├── pages/ - │ ├── _index.md - │ ├── page-1.md <-- front matter: weight = 10 - │ ├── page-2.md <-- front matter: weight = 20 - │ └── page-3.md <-- front matter: weight = 30 - └── _index.md - ``` - - When you visit page-2: - - - The `Prev` method points to page-3 - - The `Next` method points to page-1 - - {{% note %}} - Use the opposite label in your navigation links as shown in the example below. - {{% /note %}} - - ```go-html-template - {{ $pages := where .Site.RegularPages.ByWeight "Section" "pages" }} - - {{ with $pages.Next . }} - Previous - {{ end }} - - {{ with $pages.Prev . }} - Next - {{ end }} - ``` - - ## Compare to Page methods - - {{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}} ++{{% include "methods/pages/_common/next-and-prev.md" %}} diff --cc docs/content/en/methods/pages/_common/next-and-prev.md index 000000000,000000000..e0d05de84 new file mode 100644 --- /dev/null +++ b/docs/content/en/methods/pages/_common/next-and-prev.md @@@ -1,0 -1,0 +1,72 @@@ ++--- ++# Do not remove front matter. ++--- ++ ++Hugo determines the _next_ and _previous_ page by sorting the page collection according to this sorting hierarchy: ++ ++Field|Precedence|Sort direction ++:--|:--|:-- ++[`weight`]|1|descending ++[`date`]|2|descending ++[`linkTitle`]|3|descending ++[`path`]|4|descending ++ ++[`date`]: /methods/page/date/ ++[`weight`]: /methods/page/weight/ ++[`linkTitle`]: /methods/page/linktitle/ ++[`path`]: /methods/page/path/ ++ ++The sorted page collection used to determine the _next_ and _previous_ page is independent of other page collections, which may lead to unexpected behavior. ++ ++For example, with this content structure: ++ ++```text ++content/ ++├── pages/ ++│ ├── _index.md ++│ ├── page-1.md <-- front matter: weight = 10 ++│ ├── page-2.md <-- front matter: weight = 20 ++│ └── page-3.md <-- front matter: weight = 30 ++└── _index.md ++``` ++ ++And these templates: ++ ++{{< code file=layouts/_default/list.html >}} ++{{ range .Pages.ByWeight}} ++

{{ .LinkTitle }}

++{{ end }} ++{{< /code >}} ++ ++{{< code file=layouts/_default/single.html >}} ++{{ $pages := .CurrentSection.Pages.ByWeight }} ++ ++{{ with $pages.Prev . }} ++ Previous ++{{ end }} ++ ++{{ with $pages.Next . }} ++ Next ++{{ end }} ++{{< /code >}} ++ ++When you visit page-2: ++ ++- The `Prev` method points to page-3 ++- The `Next` method points to page-1 ++ ++To reverse the meaning of _next_ and _previous_ you can chain the [`Reverse`] method to the page collection definition: ++ ++{{< code file=layouts/_default/single.html >}} ++{{ $pages := .CurrentSection.Pages.ByWeight.Reverse }} ++ ++{{ with $pages.Prev . }} ++ Previous ++{{ end }} ++ ++{{ with $pages.Next . }} ++ Next ++{{ end }} ++{{< /code >}} ++ ++[`Reverse`]: /methods/pages/reverse/ diff --cc docs/content/en/render-hooks/blockquotes.md index 000000000,000000000..e0eda5c51 new file mode 100755 --- /dev/null +++ b/docs/content/en/render-hooks/blockquotes.md @@@ -1,0 -1,0 +1,171 @@@ ++--- ++title: Blockquote render hooks ++linkTitle: Blockquotes ++description: Create a blockquote render hook to override the rendering of Markdown blockquotes to HTML. ++categories: [render hooks] ++keywords: [] ++menu: ++ docs: ++ parent: render-hooks ++ weight: 30 ++weight: 30 ++toc: true ++--- ++ ++{{< new-in 0.132.0 >}} ++ ++## Context ++ ++Blockquote render hook templates receive the following [context]: ++ ++[context]: /getting-started/glossary/#context ++ ++###### AlertType ++ ++(`string`) Applicable when [`Type`](#type) is `alert`, this is the alert type converted to lowercase. See the [alerts](#alerts) section below. ++ ++###### Attributes ++ ++(`map`) The [Markdown attributes], available if you configure your site as follows: ++ ++[Markdown attributes]: /content-management/markdown-attributes/ ++ ++{{< code-toggle file=hugo >}} ++[markup.goldmark.parser.attribute] ++block = true ++{{< /code-toggle >}} ++ ++###### Ordinal ++ ++(`int`) The zero-based ordinal of the blockquote on the page. ++ ++###### Page ++ ++(`page`) A reference to the current page. ++ ++###### PageInner ++ ++(`page`) A reference to a page nested via the [`RenderShortcodes`] method. ++ ++[`RenderShortcodes`]: /methods/page/rendershortcodes ++ ++###### Position ++ ++(`string`) The position of the blockquote within the page content. ++ ++###### Text ++(`string`) The blockquote text, excluding the alert designator if present. See the [alerts](#alerts) section below. ++ ++###### Type ++ ++(`bool`) The blockquote type. Returns `alert` if the blockquote has an alert designator, else `regular`. See the [alerts](#alerts) section below. ++ ++## Examples ++ ++In its default configuration, Hugo renders Markdown blockquotes according to the [CommonMark specification]. To create a render hook that does the same thing: ++ ++[CommonMark specification]: https://spec.commonmark.org/current/ ++ ++{{< code file=layouts/_default/_markup/render-blockquote.html copy=true >}} ++
++ {{ .Text | safeHTML }} ++
++{{< /code >}} ++ ++To render a blockquote as an HTML `figure` element with an optional citation and caption: ++ ++{{< code file=layouts/_default/_markup/render-blockquote.html copy=true >}} ++
++
++ {{ .Text | safeHTML }} ++
++ {{ with .Attributes.caption }} ++
++ {{ . | safeHTML }} ++
++ {{ end }} ++
++{{< /code >}} ++ ++Then in your markdown: ++ ++```text ++> Some text ++{cite="https://gohugo.io" caption="Some caption"} ++``` ++ ++## Alerts ++ ++Also known as _callouts_ or _admonitions_, alerts are blockquotes used to emphasize critical information. For example: ++ ++{{< code file=content/example.md lang=text >}} ++> [!NOTE] ++> Useful information that users should know, even when skimming content. ++ ++> [!TIP] ++> Helpful advice for doing things better or more easily. ++ ++> [!IMPORTANT] ++> Key information users need to know to achieve their goal. ++ ++> [!WARNING] ++> Urgent info that needs immediate user attention to avoid problems. ++ ++> [!CAUTION] ++> Advises about risks or negative outcomes of certain actions. ++{{< /code >}} ++ ++ ++{{% note %}} ++This syntax is compatible with the GitHub Alert Markdown extension. ++{{% /note %}} ++ ++ ++The first line of each alert is an alert designator consisting of an exclamation point followed by the alert type, wrapped within brackets. ++ ++The blockquote render hook below renders a multilingual alert if an alert desginator is present, otherwise it renders a blockquote according to the CommonMark specification. ++ ++{{< code file=layouts/_default/_markup/render-blockquote.html copy=true >}} ++{{ $emojis := dict ++ "caution" ":exclamation:" ++ "important" ":information_source:" ++ "note" ":information_source:" ++ "tip" ":bulb:" ++ "warning" ":information_source:" ++}} ++ ++{{ if eq .Type "alert" }} ++
++

++ {{ transform.Emojify (index $emojis .AlertType) }} ++ {{ or (i18n .AlertType) (title .AlertType) }} ++

++ {{ .Text | safeHTML }} ++
++{{ else }} ++
++ {{ .Text | safeHTML }} ++
++{{ end }} ++{{< /code >}} ++ ++To override the label, create these entries in your i18n files: ++ ++{{< code-toggle file=i18n/en.toml >}} ++caution = 'Caution' ++important = 'Important' ++note = 'Note' ++tip = 'Tip' ++warning = 'Warning' ++{{< /code-toggle >}} ++ ++ ++Although you can use one template with conditional logic as shown above, you can also create separate templates for each [`Type`](#type) of blockquote: ++ ++```text ++layouts/ ++└── _default/ ++ └── _markup/ ++ ├── render-blockquote-alert.html ++ └── render-blockquote-regular.html ++``` diff --cc docs/content/en/render-hooks/code-blocks.md index 0c11c7864,000000000..d322cb88d mode 100755,000000..100755 --- a/docs/content/en/render-hooks/code-blocks.md +++ b/docs/content/en/render-hooks/code-blocks.md @@@ -1,152 -1,0 +1,152 @@@ +--- +title: Code block render hooks +linkTitle: Code blocks +description: Create a code block render hook to override the rendering of Markdown code blocks to HTML. +categories: [render hooks] +keywords: [] +menu: + docs: + parent: render-hooks - weight: 30 - weight: 30 ++ weight: 40 ++weight: 40 +toc: true +--- + +## Markdown + +This Markdown example contains a fenced code block: + +{{< code file=content/example.md lang=text >}} +```bash {class="my-class" id="my-codeblock" lineNos=inline tabWidth=2} +declare a=1 +echo "$a" +exit +``` +{{< /code >}} + +A fenced code block consists of: + +- A leading [code fence] +- An optional [info string] +- A code sample +- A trailing code fence + +[code fence]: https://spec.commonmark.org/0.31.2/#code-fence +[info string]: https://spec.commonmark.org/0.31.2/#info-string + +In the previous example, the info string contains: + +- The language of the code sample (the first word) +- An optional space-delimited or comma-delimited list of attributes (everything within braces) + +The attributes in the info string can be generic attributes or highlighting options. + +In the example above, the _generic attributes_ are `class` and `id`. In the absence of special handling within a code block render hook, Hugo adds each generic attribute to the HTML element surrounding the rendered code block. Consistent with its content security model, Hugo removes HTML event attributes such as `onclick` and `onmouseover`. Generic attributes are typically global HTML attributes, but you may include custom attributes as well. + +In the example above, the _highlighting options_ are `lineNos` and `tabWidth`. Hugo uses the [Chroma] syntax highlighter to render the code sample. You can control the appearance of the rendered code by specifying one or more [highlighting options]. + +[Chroma]: https://github.com/alecthomas/chroma/ +[highlighting options]: /functions/transform/highlight/#options + +{{% note %}} +Although `style` is a global HTML attribute, when used in an info string it is a highlighting option. +{{% /note %}} + +## Context + +Code block render hook templates receive the following [context]: + +[context]: /getting-started/glossary/#context + +###### Attributes + +(`map`) The generic attributes from the info string. + +###### Inner + +(`string`) The content between the leading and trailing code fences, excluding the info string. + +###### Options + +(`map`) The highlighting options from the info string. + +###### Ordinal + +(`int`) The zero-based ordinal of the code block on the page. + +###### Page + +(`page`) A reference to the current page. + +###### PageInner + +{{< new-in 0.125.0 >}} + +(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details). + +[`RenderShortcodes`]: /methods/page/rendershortcodes + +###### Position + +(`text.Position`) The position of the code block within the page content. + +###### Type + +(`string`) The first word of the info string, typically the code language. + +## Examples + +In its default configuration, Hugo renders fenced code blocks by passing the code sample through the Chroma syntax highlighter and wrapping the result. To create a render hook that does the same thing: + +[CommonMark specification]: https://spec.commonmark.org/current/ + +{{< code file=layouts/_default/_markup/render-codeblock.html copy=true >}} +{{ $result := transform.HighlightCodeBlock . }} +{{ $result.Wrapped }} +{{< /code >}} + +Although you can use one template with conditional logic to control the behavior on a per-language basis, you can also create language-specific templates. + +```text +layouts/ +└── _default/ + └── _markup/ + ├── render-codeblock-mermaid.html + ├── render-codeblock-python.html + └── render-codeblock.html +``` + +For example, to create a code block render hook to render [Mermaid] diagrams: + +[Mermaid]: https://mermaid.js.org/ + +{{< code file=layouts/_default/_markup/render-codeblock-mermaid.html copy=true >}} +
 +  {{- .Inner | safeHTML }}
 +
+{{ .Page.Store.Set "hasMermaid" true }} +{{< /code >}} + +Then include this snippet at the bottom of the your base template: + +{{< code file=layouts/_default/baseof.html copy=true >}} +{{ if .Store.Get "hasMermaid" }} + +{{ end }} +{{< /code >}} + +See the [diagrams] page for details. + +[diagrams]: /content-management/diagrams/#mermaid-diagrams + +## Embedded + +Hugo includes an [embedded code block render hook] to render [GoAT diagrams]. + +[embedded code block render hook]: {{% eturl render-codeblock-goat %}} +[GoAT diagrams]: /content-management/diagrams/#goat-diagrams-ascii + +{{% include "/render-hooks/_common/pageinner.md" %}} diff --cc docs/content/en/render-hooks/headings.md index c48bb11e1,000000000..8ae3b808a mode 100755,000000..100755 --- a/docs/content/en/render-hooks/headings.md +++ b/docs/content/en/render-hooks/headings.md @@@ -1,79 -1,0 +1,81 @@@ +--- +title: Heading render hooks +linkTitle: Headings +description: Create a heading render hook to override the rendering of Markdown headings to HTML. +categories: [render hooks] +keywords: [] +menu: + docs: + parent: render-hooks - weight: 40 - weight: 40 ++ weight: 50 ++weight: 50 +toc: true +--- + +## Context + +Heading render hook templates receive the following [context]: + +[context]: /getting-started/glossary/#context + +###### Anchor + +(`string`) The `id` attribute of the heading element. + +###### Attributes + - (`map`) The Markdown attributes, available if you configure your site as follows: ++(`map`) The [Markdown attributes], available if you configure your site as follows: ++ ++[Markdown attributes]: /content-management/markdown-attributes/ + +{{< code-toggle file=hugo >}} +[markup.goldmark.parser.attribute] +title = true +{{< /code-toggle >}} + +###### Level + +(`int`) The heading level, 1 through 6. + +###### Page + +(`page`) A reference to the current page. + +###### PageInner + +{{< new-in 0.125.0 >}} + +(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details). + +[`RenderShortcodes`]: /methods/page/rendershortcodes + +###### PlainText + +(`string`) The heading text as plain text. + +###### Text + +(`string`) The heading text. + +## Examples + +In its default configuration, Hugo renders Markdown headings according to the [CommonMark specification] with the addition of automatic `id` attributes. To create a render hook that does the same thing: + +[CommonMark specification]: https://spec.commonmark.org/current/ + +{{< code file=layouts/_default/_markup/render-heading.html copy=true >}} + + {{- .Text | safeHTML -}} + +{{< /code >}} + +To add an anchor link to the right of each heading: + +{{< code file=layouts/_default/_markup/render-heading.html copy=true >}} + + {{ .Text | safeHTML }} + # + +{{< /code >}} + +{{% include "/render-hooks/_common/pageinner.md" %}} diff --cc docs/content/en/render-hooks/images.md index 2d9b5e2e5,000000000..1638ceeae mode 100755,000000..100755 --- a/docs/content/en/render-hooks/images.md +++ b/docs/content/en/render-hooks/images.md @@@ -1,163 -1,0 +1,165 @@@ +--- +title: Image render hooks +linkTitle: Images +description: Create an image render to hook override the rendering of Markdown images to HTML. +categories: [render hooks] +keywords: [] +menu: + docs: + parent: render-hooks - weight: 50 - weight: 50 ++ weight: 60 ++weight: 60 +toc: true +--- + +## Markdown + +A Markdown image has three components: the image description, the image destination, and optionally the image title. + +```text +![white kitten](/images/kitten.jpg "A kitten!") + ------------ ------------------ --------- + description destination title +``` + +These components are passed into the render hook [context] as shown below. + +[context]: /getting-started/glossary/#context + +## Context + +Image render hook templates receive the following context: + +###### Attributes + - (`map`) The Markdown attributes, available if you configure your site as follows: ++(`map`) The [Markdown attributes], available if you configure your site as follows: ++ ++[Markdown attributes]: /content-management/markdown-attributes/ + +{{< code-toggle file=hugo >}} +[markup.goldmark.parser] +wrapStandAloneImageWithinParagraph = false +[markup.goldmark.parser.attribute] +block = true +{{< /code-toggle >}} + +###### Destination + +(`string`) The image destination. + +###### IsBlock + +(`bool`) Returns true if a standalone image is not wrapped within a paragraph element. + +###### Ordinal + +(`int`) The zero-based ordinal of the image on the page. + +###### Page + +(`page`) A reference to the current page. + +###### PageInner + +{{< new-in 0.125.0 >}} + +(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details). + +[`RenderShortcodes`]: /methods/page/rendershortcodes + +###### PlainText + +(`string`) The image description as plain text. + +###### Text + +(`string`) The image description. + +###### Title + +(`string`) The image title. + +## Examples + +{{% note %}} +With inline elements such as images and links, remove leading and trailing whitespace using the `{{‑ ‑}}` delimiter notation to prevent whitespace between adjacent inline elements and text. +{{% /note %}} + +In its default configuration, Hugo renders Markdown images according to the [CommonMark specification]. To create a render hook that does the same thing: + +[CommonMark specification]: https://spec.commonmark.org/current/ + +{{< code file=layouts/_default/_markup/render-image.html copy=true >}} +{{ . }} +{{- /* chomp trailing newline */ -}} +{{< /code >}} + +To render standalone images within `figure` elements: + +{{< code file=layouts/_default/_markup/render-image.html copy=true >}} +{{- if .IsBlock -}} +
+ {{ . }} + {{- with .Title }}
{{ . }}
{{ end -}} +
+{{- else -}} + {{ . }} +{{- end -}} +{{< /code >}} + +Note that the above requires the following site configuration: + +{{< code-toggle file=hugo >}} +[markup.goldmark.parser] +wrapStandAloneImageWithinParagraph = false +{{< /code-toggle >}} + +## Default + +{{< new-in 0.123.0 >}} + +Hugo includes an [embedded image render hook] to resolve Markdown image destinations. Disabled by default, you can enable it in your site configuration: + +[embedded image render hook]: {{% eturl render-image %}} + +{{< code-toggle file=hugo >}} +[markup.goldmark.renderHooks.image] +enableDefault = true +{{< /code-toggle >}} + +A custom render hook, even when provided by a theme or module, will override the embedded render hook regardless of the configuration setting above. + +{{% note %}} +The embedded image render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites. + +[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles +{{% /note %}} + +The embedded image render hook resolves internal Markdown destinations by looking for a matching [page resource], falling back to a matching [global resource]. Remote destinations are passed through, and the render hook will not throw an error or warning if it is unable to resolve a destination. + +[page resource]: /getting-started/glossary/#page-resource +[global resource]: /getting-started/glossary/#global-resource + +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: + +{{< code-toggle file=hugo >}} +[[module.mounts]] +source = 'assets' +target = 'assets' + +[[module.mounts]] +source = 'static' +target = 'assets' +{{< /code-toggle >}} + +Note that the embedded image render hook does not perform image processing. Its sole purpose is to resolve Markdown image destinations. + +{{% include "/render-hooks/_common/pageinner.md" %}} diff --cc docs/content/en/render-hooks/introduction.md index 8268b2ec7,000000000..3745fc398 mode 100755,000000..100755 --- a/docs/content/en/render-hooks/introduction.md +++ b/docs/content/en/render-hooks/introduction.md @@@ -1,85 -1,0 +1,88 @@@ +--- +title: Introduction +description: An introduction to Hugo's render hooks. +categories: [render hooks] +keywords: [] +menu: + docs: + identifier: render-hooks-introduction + parent: render-hooks + weight: 20 +weight: 20 +--- + +When rendering Markdown to HTML, render hooks override the conversion. Each render hook is a template, with one template for each supported element type: + ++- [Blockquotes](/render-hooks/blockquotes) +- [Code blocks](/render-hooks/code-blocks) +- [Headings](/render-hooks/headings) +- [Images](/render-hooks/images) +- [Links](/render-hooks/links) ++- [Passthrough elements](/render-hooks/passthrough) + +{{% note %}} +Hugo supports multiple [content formats] including Markdown, HTML, AsciiDoc, Emacs Org Mode, Pandoc, and reStructuredText. + +The render hook capability is limited to Markdown. You cannot create render hooks for the other content formats. + +[content formats]: /content-management/formats/ +{{% /note %}} + +For example, consider this Markdown: + +```text +[Hugo](https://gohugo.io) + +![kitten](kitten.jpg) +``` + +Without link or image render hooks, this example above is rendered to: + +```html +

Hugo

+

kitten

+``` + +By creating link and image render hooks, you can alter the conversion from Markdown to HTML. For example: + +```html +

Hugo

+

kitten

+``` + +Each render hook is a template, with one template for each supported element type: + +```text +layouts/ +└── _default/ + └── _markup/ ++ ├── render-blockquote.html + ├── render-codeblock.html + ├── render-heading.html + ├── render-image.html + └── render-link.html +``` + +The template lookup order allows you to create different render hooks for each page [type], [kind], language, and [output format]. For example: + +```text +layouts/ +├── _default/ +│ └── _markup/ +│ ├── render-link.html +│ └── render-link.rss.xml +├── books/ +│ └── _markup/ +│ ├── render-link.html +│ └── render-link.rss.xml +└── films/ + └── _markup/ + ├── render-link.html + └── render-link.rss.xml +``` + +[kind]: /getting-started/glossary/#page-kind +[output format]: /getting-started/glossary/#output-format +[type]: /getting-started/glossary/#content-type + +The remaining pages in this section describe each type of render hook, including examples and the context received by each template. diff --cc docs/content/en/render-hooks/links.md index bf0485068,000000000..79c3d6926 mode 100755,000000..100755 --- a/docs/content/en/render-hooks/links.md +++ b/docs/content/en/render-hooks/links.md @@@ -1,133 -1,0 +1,133 @@@ +--- +title: Link render hooks +linkTitle: Links +description: Create a link render hook to override the rendering of Markdown links to HTML. +categories: [render hooks] +keywords: [] +menu: + docs: + parent: render-hooks - weight: 60 - weight: 60 ++ weight: 70 ++weight: 70 +toc: true +--- + +## Markdown + +A Markdown link has three components: the link text, the link destination, and optionally the link title. + +```text +[Post 1](/posts/post-1 "My first post") + ------ ------------- ------------- + text destination title +``` + +These components are passed into the render hook [context] as shown below. + +[context]: /getting-started/glossary/#context + +## Context + +Link render hook templates receive the following context: + +[context]: /getting-started/glossary/#context + +###### Destination + +(`string`) The link destination. + +###### Page + +(`page`) A reference to the current page. + +###### PageInner + +{{< new-in 0.125.0 >}} + +(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details). + +[`RenderShortcodes`]: /methods/page/rendershortcodes + +###### PlainText + +(`string`) The link description as plain text. + +###### Text + +(`string`) The link description. + +###### Title + +(`string`) The link title. + +## Examples + +{{% note %}} +With inline elements such as images and links, remove leading and trailing whitespace using the `{{‑ ‑}}` delimiter notation to prevent whitespace between adjacent inline elements and text. +{{% /note %}} + +In its default configuration, Hugo renders Markdown links according to the [CommonMark specification]. To create a render hook that does the same thing: + +[CommonMark specification]: https://spec.commonmark.org/current/ + +{{< code file=layouts/_default/_markup/render-link.html copy=true >}} + + {{- with .Text | safeHTML }}{{ . }}{{ end -}} + +{{- /* chomp trailing newline */ -}} +{{< /code >}} + +To include a `rel` attribute set to `external` for external links: + +{{< code file=layouts/_default/_markup/render-link.html copy=true >}} +{{- $u := urls.Parse .Destination -}} + + {{- with .Text | safeHTML }}{{ . }}{{ end -}} + +{{- /* chomp trailing newline */ -}} +{{< /code >}} + +## Default + +{{< new-in 0.123.0 >}} + +Hugo includes an [embedded link render hook] to resolve Markdown link destinations. Disabled by default, you can enable it in your site configuration: + +[embedded link render hook]: {{% eturl render-link %}} + +{{< code-toggle file=hugo >}} +[markup.goldmark.renderHooks.link] +enableDefault = true +{{< /code-toggle >}} + +A custom render hook, even when provided by a theme or module, will override the embedded render hook regardless of the configuration setting above. + +{{% note %}} +The embedded link render hook is automatically enabled for multilingual single-host sites if [duplication of shared page resources] is disabled. This is the default configuration for multilingual single-host sites. + +[duplication of shared page resources]: /getting-started/configuration-markup/#duplicateresourcefiles +{{% /note %}} + +The embedded link render hook resolves internal Markdown destinations by looking for a matching page, falling back to a matching [page resource], then falling back to a matching [global resource]. Remote destinations are passed through, and the render hook will not throw an error or warning if it is unable to resolve a destination. + +[page resource]: /getting-started/glossary/#page-resource +[global resource]: /getting-started/glossary/#global-resource + +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: + +{{< code-toggle file=hugo >}} +[[module.mounts]] +source = 'assets' +target = 'assets' + +[[module.mounts]] +source = 'static' +target = 'assets' +{{< /code-toggle >}} + +{{% include "/render-hooks/_common/pageinner.md" %}} diff --cc docs/content/en/render-hooks/passthrough.md index 000000000,000000000..3b82116e6 new file mode 100755 --- /dev/null +++ b/docs/content/en/render-hooks/passthrough.md @@@ -1,0 -1,0 +1,125 @@@ ++--- ++title: Passthrough render hooks ++linkTitle: Passthrough ++description: Create a passthrough render hook to override the rendering of text snippets captured by the Goldmark passthrough extension. ++categories: [render hooks] ++keywords: [] ++menu: ++ docs: ++ parent: render-hooks ++ weight: 80 ++weight: 80 ++toc: true ++--- ++ ++{{< new-in 0.132.0 >}} ++ ++## Overview ++ ++Hugo uses [Goldmark] to render Markdown to HTML. Goldmark supports custom extensions to extend its core functionality. The Goldmark [passthrough extension] captures and preserves raw Markdown within delimited snippets of text, including the delimiters themselves. These are known as _passthrough elements_. ++ ++[Goldmark]: https://github.com/yuin/goldmark ++[passthrough extension]: /getting-started/configuration-markup/#passthrough ++ ++Depending on your choice of delimiters, Hugo will classify a passthrough element as either _block_ or _inline_. Consider this contrived example: ++ ++{{< code file=content/sample.md >}} ++This is a ++ ++\[block\] ++ ++passthrough element with opening and closing block delimiters. ++ ++This is an \(inline\) passthrough element with opening and closing inline delimiters. ++{{< /code >}} ++ ++Update your site configuration to enable the passthrough extension and define opening and closing delimiters for each passthrough element type, either `block` or `inline`. For example: ++ ++{{< code-toggle file=hugo >}} ++[markup.goldmark.extensions.passthrough] ++enable = true ++[markup.goldmark.extensions.passthrough.delimiters] ++block = [['\[', '\]'], ['$$', '$$']] ++inline = [['\(', '\)']] ++{{< /code-toggle >}} ++ ++In the example above there are two sets of `block` delimiters. You may use either one in your Markdown. ++ ++The Goldmark passthrough extension is often used in conjunction with the MathJax or KaTeX display engine to render [mathematical expressions] written in [LaTeX] or [Tex]. ++ ++[mathematical expressions]: /content-management/mathematics/ ++[LaTeX]: https://www.latex-project.org/ ++[Tex]: https://en.wikipedia.org/wiki/TeX ++ ++To enable custom rendering of passthrough elements, create a render hook. ++ ++## Context ++ ++Passthrough render hook templates receive the following [context]: ++ ++[context]: /getting-started/glossary/#context ++ ++###### Attributes ++ ++(`map`) The [Markdown attributes], available if you configure your site as follows: ++ ++[Markdown attributes]: /content-management/markdown-attributes/ ++ ++{{< code-toggle file=hugo >}} ++[markup.goldmark.parser.attribute] ++block = true ++{{< /code-toggle >}} ++ ++Hugo populates the `Attributes` map for _block_ passthrough elements. Markdown attributes are not applicable to _inline_ elements. ++ ++###### Inner ++(`string`) The inner content of the passthrough element, excluding the delimiters. ++ ++###### Ordinal ++ ++(`int`) The zero-based ordinal of the passthrough element on the page. ++ ++###### Page ++ ++(`page`) A reference to the current page. ++ ++###### PageInner ++ ++(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details). ++ ++[`RenderShortcodes`]: /methods/page/rendershortcodes ++ ++###### Position ++ ++(`string`) The position of the passthrough element within the page content. ++ ++###### Type ++ ++(`bool`) The passthrough element type, either `block` or `inline`. ++ ++## Example ++ ++As an alternative to rendering mathematical expressions with the MathJax or KaTeX display engine, create a passthrough render hook which calls the [`transform.ToMath`] function: ++ ++[`transform.ToMath`]: /functions/transform/tomath/ ++ ++{{< code file=layouts/_default/_markup/render-passthrough.html copy=true >}} ++{{ if eq .Type "block" }} ++ {{ $opts := dict "displayMode" true }} ++ {{ transform.ToMath .Inner $opts }} ++{{ else }} ++ {{ transform.ToMath .Inner }} ++{{ end }} ++{{< /code >}} ++ ++Although you can use one template with conditional logic as shown above, you can also create separate templates for each [`Type`](#type) of passthrough element: ++ ++```text ++layouts/ ++└── _default/ ++ └── _markup/ ++ ├── render-passthrough-block.html ++ └── render-passthrough-inline.html ++``` ++ ++{{% include "/render-hooks/_common/pageinner.md" %}} diff --cc docs/content/en/templates/embedded.md index 5fbbb8d96,000000000..888f4f342 mode 100644,000000..100644 --- a/docs/content/en/templates/embedded.md +++ b/docs/content/en/templates/embedded.md @@@ -1,223 -1,0 +1,223 @@@ +--- +title: Embedded templates +description: Hugo provides embedded templates for common use cases. +categories: [templates] +keywords: [] +menu: + docs: + parent: templates + weight: 200 +weight: 200 +toc: true +aliases: [/templates/internal] +--- + +## Disqus + +{{% note %}} +To override Hugo's embedded Disqus template, copy the [source code] 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" . }}` + +[`partial`]: /functions/partials/include/ +[source code]: {{% eturl disqus %}} +{{% /note %}} + +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. + +[Disqus]: https://disqus.com +[signing up]: https://disqus.com/profile/signup/ + +To include the embedded template: + +```go-html-template +{{ template "_internal/disqus.html" . }} +``` + +### Configure Disqus + +To use Hugo's Disqus template, first set up a single configuration value: + +{{< code-toggle file="hugo" >}} +[services.disqus] +shortname = 'your-disqus-shortname' +{{}} + +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` + +## Google Analytics + +{{% note %}} +To override Hugo's embedded Google Analytics template, copy the [source code] 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" . }}` + +[`partial`]: /functions/partials/include/ +[source code]: {{% eturl google_analytics %}} +{{% /note %}} + +Hugo includes an embedded template supporting [Google Analytics 4]. + +[Google Analytics 4]: https://support.google.com/analytics/answer/10089681 + +To include the embedded template: + +```go-html-template +{{ template "_internal/google_analytics.html" . }} +``` + +### Configure Google Analytics + +Provide your tracking ID in your configuration file: + +{{< code-toggle file=hugo >}} +[services.googleAnalytics] +ID = "G-MEASUREMENT_ID" +{{}} + +To use this value in your own template, access the configured ID with `{{ site.Config.Services.GoogleAnalytics.ID }}`. + +## Open Graph + +{{% note %}} +To override Hugo's embedded Open Graph template, copy the [source code] 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" . }}` + +[`partial`]: /functions/partials/include/ +[source code]: {{% eturl opengraph %}} +{{% /note %}} + +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" . }} +``` + +### Configure 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 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 = [] +{{}} + +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*` or `*cover*,*thumbnail*` 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 ``. Use the `https://youtu.be/` format with YouTube videos (example: `https://youtu.be/qtIqKaDlqXo`). + +## Schema + +{{% note %}} +To override Hugo's embedded Schema template, copy the [source code] 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" . }}` + +[`partial`]: /functions/partials/include/ +[source code]: {{% eturl schema %}} +{{% /note %}} + +Hugo includes an embedded template to render [microdata] `meta` elements within the `head` element of your templates. + +[microdata]: https://html.spec.whatwg.org/multipage/microdata.html#microdata + +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] 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" . }}` + +[`partial`]: /functions/partials/include/ +[source code]: {{% eturl twitter_cards %}} +{{% /note %}} + +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" . }} +``` + +### Configure X (Twitter) 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 file=content/blog/my-post.md >}} +title = "Post title" +description = "Text about this post" +images = ["post-cover.png"] +{{}} + - If `images` aren't specified in the page front-matter, then hugo searches for [image page resources](/content-management/image-processing/) with `feature`, `cover`, or `thumbnail` in their name. ++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](/getting-started/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" copy=false >}} +[params.social] +twitter = "GoHugoIO" +{{}} + +NOTE: The `@` will be added for you + +```html + +``` diff --cc docs/content/en/templates/introduction.md index bb8702717,000000000..0a3ff2b0f mode 100644,000000..100644 --- a/docs/content/en/templates/introduction.md +++ b/docs/content/en/templates/introduction.md @@@ -1,563 -1,0 +1,577 @@@ +--- +title: Introduction to templating +linkTitle: Introduction +description: Create templates to render your content, resources, and data. +categories: [templates,fundamentals] +keywords: [] +menu: + docs: + identifier: templates-introduction + parent: templates + weight: 20 +weight: 20 +toc: true +--- + +A template is a file in the layouts directory of a project, theme, or module. Templates use [variables] , [functions], and [methods] to transform your content, resources, and data into a published page. + +[functions]: /functions/ +[methods]: /methods/ +[variables]: #variables + +{{% note %}} +Hugo uses Go's [text/template] and [html/template] packages. + +The text/template package implements data-driven templates for generating textual output, while the html/template package implements data-driven templates for generating HTML output safe against code injection. + +By default, Hugo uses the html/template package when rendering HTML files. + +[text/template]: https://pkg.go.dev/text/template +[html/template]: https://pkg.go.dev/html/template +{{% /note %}} + +For example, this HTML template initializes the `$v1` and `$v2` variables, then displays them and their product within an HTML paragraph. + +```go-html-template +{{ $v1 := 6 }} +{{ $v2 := 7 }} +

The product of {{ $v1 }} and {{ $v2 }} is {{ mul $v1 $v2 }}.

+``` + +While HTML templates are the most common, you can create templates for any [output format] including CSV, JSON, RSS, and plain text. + +[output format]: /templates/output-formats/ + +## Context + +The most important concept to understand before creating a template is _context_, the data passed into each template. The data may be a simple value, or more commonly [objects] and associated [methods]. + +[objects]: /getting-started/glossary/#object +[methods]: /getting-started/glossary/#method + +For example, a template for a single page receives a `Page` object, and the `Page` object provides methods to return values or perform actions. + +### Current context + +Within a template, the dot (`.`) represents the current context. + +{{< code file=layouts/_default/single.html >}} +

{{ .Title }}

+{{< /code >}} + +In the example above the dot represents the `Page` object, and we call its [`Title`] method to return the title as defined in [front matter]. + +[front matter]: /content-management/front-matter/ +[`Title`]: /methods/page/title + +The current context may change within a template. For example, at the top of a template the context might be a `Page` object, but we rebind the context to another value or object within [`range`] or [`with`] blocks. + +[`range`]: /functions/go-template/range/ +[`with`]: /functions/go-template/with/ + +{{< code file=layouts/_default/single.html >}} +

{{ .Title }}

+ +{{ range slice "foo" "bar" }} +

{{ . }}

+{{ end }} + +{{ with "baz" }} +

{{ . }}

+{{ end }} +{{< /code >}} + +In the example above, the context changes as we `range` through the [slice] of values. In the first iteration the context is "foo", and in the second iteration the context is "bar". Inside of the `with` block the context is "baz". Hugo renders the above to: + +[slice]: /getting-started/glossary/#slice + +```html +

My Page Title

+

foo

+

bar

+

baz

+``` + +### Template context + +Within a `range` or `with` block you can access the context passed into the template by prepending a dollar sign (`$`) to the dot: + +{{< code file=layouts/_default/single.html >}} +{{ with "foo" }} +

{{ $.Title }} - {{ . }}

+{{ end }} +{{< /code >}} + +Hugo renders this to: + +```html +

My Page Title - foo

+``` + +{{% note %}} +Make sure that you thoroughly understand the concept of _context_ before you continue reading. The most common templating errors made by new users relate to context. +{{% /note %}} + +## Actions + +In the examples above the paired opening and closing braces represent the beginning and end of a template action, a data evaluation or control structure within a template. + +A template action may contain literal values ([boolean], [string], [integer], and [float]), variables, functions, and methods. + +[boolean]: /getting-started/glossary/#boolean +[string]: /getting-started/glossary/#string +[integer]: /getting-started/glossary/#integer +[float]: /getting-started/glossary/#float + +{{< code file=layouts/_default/single.html >}} +{{ $convertToLower := true }} +{{ if $convertToLower }} +

{{ strings.ToLower .Title }}

+{{ end }} +{{< /code >}} + +In the example above: + +- `$convertToLower` is a variable +- `true` is a literal boolean value +- `strings.ToLower` is a function that converts all characters to lowercase +- `Title` is a method on a the `Page` object + +Hugo renders the above to: + +```html + + +

my page title

+ +``` + +### Whitespace + +Notice the blank lines and indentation in the previous example? Although irrelevant in production when you typically minify the output, you can remove the adjacent whitespace by using template action delimiters with hyphens: + +{{< code file=layouts/_default/single.html >}} +{{- $convertToLower := true -}} +{{- if $convertToLower -}} +

{{ strings.ToLower .Title }}

+{{- end -}} +{{< /code >}} + +Hugo renders this to: + +```html +

my page title

+``` + +Whitespace includes spaces, horizontal tabs, carriage returns, and newlines. + +### Pipes + +Within a template action you may [pipe] a value to function or method. The piped value becomes the final argument to the function or method. For example, these are equivalent: + +[pipe]: /getting-started/glossary/#pipeline + +```go-html-template +{{ strings.ToLower "Hugo" }} → hugo +{{ "Hugo" | strings.ToLower }} → hugo +``` + +You can pipe the result of one function or method into another. For example, these are equivalent: + +```go-html-template +{{ strings.TrimSuffix "o" (strings.ToLower "Hugo") }} → hug +{{ "Hugo" | strings.ToLower | strings.TrimSuffix "o" }} → hug +``` + +These are also equivalent: + +```go-html-template +{{ mul 6 (add 2 5) }} → 42 +{{ 5 | add 2 | mul 6 }} → 42 +``` + +{{% note %}} +Remember that the piped value becomes the final argument to the function or method to which you are piping. +{{% /note %}} + +### Line splitting + +You can split a template action over two or more lines. For example, these are equivalent: + +```go-html-template +{{ $v := or .Site.Language.LanguageName .Site.Language.Lang }} + +{{ $v := or + .Site.Language.LanguageName + .Site.Language.Lang +}} +``` + +You can also split [raw string literals] over two or more lines. For example, these are equivalent: + +[raw string literals]: /getting-started/glossary/#string-literal-raw + +```go-html-template +{{ $msg := "This is line one.\nThis is line two." }} + +{{ $msg := `This is line one. +This is line two.` +}} +``` + +## Variables + +A variable is a user-defined [identifier] prepended with a dollar sign (`$`), representing a value of any data type, initialized or assigned within a template action. For example, `$foo` and `$bar` are variables. + +[identifier]: /getting-started/glossary/#identifier + +Variables may contain [scalars], [slices], [maps], or [objects]. + +[scalars]: /getting-started/glossary/#scalar +[slices]: /getting-started/glossary/#slice +[maps]: /getting-started/glossary/#map +[objects]: /getting-started/glossary/#object + +Use `:=` to initialize a variable, and use `=` to assign a value to a variable that has been previously initialized. For example: + +```go-html-template +{{ $total := 3 }} +{{ range slice 7 11 21 }} + {{ $total = add $total . }} +{{ end }} +{{ $total }} → 42 +``` + +Variables initialized inside of an `if`, `range`, or `with` block are scoped to the block. Variables initialized outside of these blocks are scoped to the template. + +With variables that represent a slice or map, use the [`index`] function to return the desired value. + +[`index`]: /functions/collections/indexfunction/ + +```go-html-template +{{ $slice := slice "foo" "bar" "baz" }} +{{ index $slice 2 }} → baz + +{{ $map := dict "a" "foo" "b" "bar" "c" "baz" }} +{{ index $map "c" }} → baz +``` + +{{% note %}} +Slices and arrays are zero-based; element 0 is the first element. +{{% /note %}} + +With variables that represent a map or object, [chain] identifiers to return the desired value or to access the desired method. + +[chain]: /getting-started/glossary/#chain + +```go-html-template +{{ $map := dict "a" "foo" "b" "bar" "c" "baz" }} +{{ $map.c }} → baz + +{{ $homePage := .Site.Home }} +{{ $homePage.Title }} → My Homepage +``` + +{{% note %}} +As seen above, object and method names are capitalized. Although not required, to avoid confusion we recommend beginning variable and map key names with a lowercase letter or underscore. +{{% /note %}} + +## Functions + +Used within a template action, a function takes one or more arguments and returns a value. Unlike methods, functions are not associated with an object. + +Go's text/template and html/template packages provide a small set of functions, operators, and statements for general use. See the [go-templates] section of the function documentation for details. + +[go-templates]: /functions/go-template/ + +Hugo provides hundreds of custom [functions] categorized by namespace. For example, the `strings` namespace includes these and other functions: + +[functions]: /functions + +Function|Alias +:--|:-- +[`strings.ToLower`](/functions/strings/tolower)|`lower` +[`strings.ToUpper`](/functions/strings/toupper)|`upper` +[`strings.Replace`](/functions/strings/replace)|`replace` + +As shown above, frequently used functions have an alias. Use aliases in your templates to reduce code length. + +When calling a function, separate the arguments from the function, and from each other, with a space. For example: + +```go-html-template +{{ $total := add 1 2 3 4 }} +``` + +## Methods + +Used within a template action and associated with an object, a method takes zero or more arguments and either returns a value or performs an action. + +The most commonly accessed objects are the [`Page`] and [`Site`] objects. This is a small sampling of the [methods] available to each object. + +[`Site`]: /methods/site/ +[`Page`]: /methods/page/ +[methods]: /methods/ + +Object|Method|Description +:--|:--|:-- +`Page`|[`Date`](methods/page/date/)|Returns the date of the given page. +`Page`|[`Params`](methods/page/params/)|Returns a map of custom parameters as defined in the front matter of the given page. +`Page`|[`Title`](methods/page/title/)|Returns the title of the given page. +`Site`|[`Data`](methods/site/data/)|Returns a data structure composed from the files in the data directory. +`Site`|[`Params`](methods/site/params/)|Returns a map of custom parameters as defined in the site configuration. +`Site`|[`Title`](methods/site/title/)|Returns the title as defined in the site configuration. + +Chain the method to its object with a dot (`.`) as shown below, remembering that the leading dot represents the [current context]. + +[current context]: #current-context + +{{< code file=layouts/_default/single.html >}} +{{ .Site.Title }} → My Site Title +{{ .Page.Title }} → My Page Title +{{< /code >}} + +The context passed into most templates is a `Page` object, so this is equivalent to the previous example: + +{{< code file=layouts/_default/single.html >}} +{{ .Site.Title }} → My Site Title +{{ .Title }} → My Page Title +{{< /code >}} + +Some methods take an argument. Separate the argument from the method with a space. For example: + +{{< code file=layouts/_default/single.html >}} +{{ $page := .Page.GetPage "/books/les-miserables" }} +{{ $page.Title }} → Les Misérables +{{< /code >}} + +## Comments + +{{% note %}} +Do not attempt to use HTML comment delimiters to comment out template code. + +Hugo strips HTML comments when rendering a page, but first evaluates any template code within the HTML comment delimiters. Depending on the template code within the HTML comment delimiters, this could cause unexpected results or fail the build. +{{% /note %}} + +Template comments are similar to template actions. Paired opening and closing braces represent the beginning and end of a comment. For example: + +```text +{{/* This is an inline comment. */}} +{{- /* This is an inline comment with adjacent whitespace removed. */ -}} +``` + +Code within a comment is not parsed, executed, or displayed. Comments may be inline, as shown above, or in block form: + +```text +{{/* +This is a block comment. +*/}} + +{{- /* +This is a block comment with +adjacent whitespace removed. +*/ -}} +``` + +You may not nest one comment inside of another. + +To render an HTML comment, pass a string through the [`safeHTML`] template function. For example: + +[`safeHTML`]: /functions/safe/html + +```go-html-template +{{ "" | safeHTML }} +{{ printf "" .Site.Title | safeHTML }} +``` + +## Include + +Use the [`template`] function to include one or more of Hugo's [embedded templates]: + +[embedded templates]: /templates/embedded/ + +```go-html-template +{{ template "_internal/google_analytics.html" . }} +{{ template "_internal/opengraph" . }} +{{ template "_internal/pagination.html" . }} +{{ template "_internal/schema.html" . }} +{{ template "_internal/twitter_cards.html" . }} +``` + +[`partial`]: /functions/partials/include/ +[`partialCached`]: /functions/partials/includecached/ +[`template`]: functions/go-template/template/ + +Use the [`partial`] or [`partialCached`] function to include one or more [partial templates]: + +[partial templates]: /templates/partial + +```go-html-template +{{ partial "breadcrumbs.html" . }} +{{ partialCached "css.html" . }} +``` + +Create your partial templates in the layouts/partials directory. + +{{% note %}} +In the examples above, note that we are passing the current context (the dot) to each of the templates. +{{% /note %}} + +## Examples + +This limited set of contrived examples demonstrates some of concepts described above. Please see the [functions], [methods], and [templates] documentation for specific examples. + +[templates]: /templates/ + +### Conditional blocks + +See documentation for [`if`], [`else`], and [`end`]. + +[`if`]: /functions/go-template/if/ +[`else`]: /functions/go-template/else/ +[`end`]: /functions/go-template/end/ + +```go-html-template +{{ $var := 42 }} +{{ if eq $var 6 }} + {{ print "var is 6" }} +{{ else if eq $var 7 }} + {{ print "var is 7" }} +{{ else if eq $var 42 }} + {{ print "var is 42" }} +{{ else }} + {{ print "var is something else" }} +{{ end }} +``` + +### Logical operators + +See documentation for [`and`] and [`or`]. + +[`and`]: /functions/go-template/and +[`or`]: /functions/go-template/or + +```go-html-template +{{ $v1 := true }} +{{ $v2 := false }} +{{ $v3 := false }} +{{ $result := false }} + +{{ if and $v1 $v2 $v3 }} + {{ $result = true }} +{{ end }} +{{ $result }} → false + +{{ if or $v1 $v2 $v3 }} + {{ $result = true }} +{{ end }} +{{ $result }} → true +``` + +### Loops + +See documentation for [`range`], [`else`], and [`end`]. + +[`range`]: /functions/go-template/range/ + +```go-html-template +{{ $s := slice "foo" "bar" "baz" }} +{{ range $s }} +

{{ . }}

+{{ else }} +

The collection is empty

+{{ end }} +``` + +Use the [`seq`] function to loop a specified number of times: + +[`seq`]: /functions/collections/seq + +```go-html-template +{{ $total := 0 }} +{{ range seq 4 }} + {{ $total = add $total . }} +{{ end }} +{{ $total }} → 10 +``` + +### Rebind context + +See documentation for [`with`], [`else`], and [`end`]. + +[`with`]: /functions/go-template/with/ + +```go-html-template +{{ $var := "foo" }} +{{ with $var }} + {{ . }} → foo +{{ else }} + {{ print "var is falsy" }} +{{ end }} +``` + ++To test multiple conditions: ++ ++```go-html-template ++{{ $v1 := 0 }} ++{{ $v2 := 42 }} ++{{ with $v1 }} ++ {{ . }} ++{{ else with $v2 }} ++ {{ . }} → 42 ++{{ else }} ++ {{ print "v1 and v2 are falsy" }} ++{{ end }} ++``` ++ +### Access site parameters + +See documentation for the [`Params`](/methods/site/params/) method on a `Site` object. + +With this site configuration: + +{{< code-toggle file=hugo >}} +title = 'ABC Widgets' +baseURL = 'https://example.org' +[params] + subtitle = 'The Best Widgets on Earth' + copyright-year = '2023' + [params.author] + email = 'jsmith@example.org' + name = 'John Smith' + [params.layouts] + rfc_1123 = 'Mon, 02 Jan 2006 15:04:05 MST' + rfc_3339 = '2006-01-02T15:04:05-07:00' +{{< /code-toggle >}} + +Access the custom site parameters by chaining the identifiers: + +```go-html-template +{{ .Site.Params.subtitle }} → The Best Widgets on Earth +{{ .Site.Params.author.name }} → John Smith + +{{ $layout := .Site.Params.layouts.rfc_1123 }} +{{ .Site.Lastmod.Format $layout }} → Tue, 17 Oct 2023 13:21:02 PDT +``` + +### Access page parameters + +See documentation for the [`Params`](/methods/page/params/) method on a `Page` object. + +With this front matter: + +{{< code-toggle file=content/news/annual-conference.md >}} +title = 'Annual conference' +date = 2023-10-17T15:11:37-07:00 +[params] +display_related = true +[params.author] + email = 'jsmith@example.org' + name = 'John Smith' +{{< /code-toggle >}} + +Access the custom page parameters by chaining the identifiers: + +```go-html-template +{{ .Params.display_related }} → true +{{ .Params.author.name }} → John Smith +``` diff --cc docs/content/en/templates/menu.md index de103803c,000000000..bd0bc5569 mode 100644,000000..100644 --- a/docs/content/en/templates/menu.md +++ b/docs/content/en/templates/menu.md @@@ -1,133 -1,0 +1,133 @@@ +--- +title: Menus +description: Create templates to render one or more menus. +categories: [templates] +keywords: [] +menu: + docs: + identifier: templates-menu + parent: templates + weight: 180 +weight: 180 +toc: true +aliases: [/templates/menus/,/templates/menu-templates/] +--- + +## Overview + +After [defining menu entries], use [menu methods] to render a menu. + +Three factors determine how to render a menu: + +1. The method used to define the menu entries: [automatic], [in front matter], or [in site configuration] +1. The menu structure: flat or nested +1. The method used to [localize the menu entries]: site configuration or translation tables + +The example below handles every combination. + +## Example + +This partial template recursively "walks" a menu structure, rendering a localized, accessible nested list. + +{{< code file=layouts/partials/menu.html copy=true >}} +{{- $page := .page }} +{{- $menuID := .menuID }} + +{{- with index site.Menus $menuID }} + +{{- end }} + +{{- define "partials/inline/menu/walk.html" }} + {{- $page := .page }} + {{- range .menuEntries }} + {{- $attrs := dict "href" .URL }} + {{- if $page.IsMenuCurrent .Menu . }} + {{- $attrs = merge $attrs (dict "class" "active" "aria-current" "page") }} + {{- else if $page.HasMenuCurrent .Menu .}} + {{- $attrs = merge $attrs (dict "class" "ancestor" "aria-current" "true") }} + {{- end }} + {{- $name := .Name }} + {{- with .Identifier }} + {{- with T . }} + {{- $name = . }} + {{- end }} + {{- end }} +
  • + {{ $name }} + {{- with .Children }} +
      + {{- partial "inline/menu/walk.html" (dict "page" $page "menuEntries" .) }} +
    + {{- end }} +
  • + {{- end }} +{{- end }} +{{< /code >}} + +Call the partial above, passing a menu ID and the current page in context. + +{{< code file=layouts/_default/single.html >}} +{{ partial "menu.html" (dict "menuID" "main" "page" .) }} +{{ partial "menu.html" (dict "menuID" "footer" "page" .) }} +{{< /code >}} + +## Page references + +Regardless of how you [define menu entries], an entry associated with a page has access to page context. + +This simplistic example renders a page parameter named `version` next to each entry's `name`. Code defensively using `with` or `if` to handle entries where (a) the entry points to an external resource, or (b) the `version` parameter is not defined. + +{{< code file=layouts/_default/single.html >}} +{{- range site.Menus.main }} + + {{ .Name }} + {{- with .Page }} + {{- with .Params.version -}} + ({{ . }}) + {{- end }} + {{- end }} + +{{- end }} +{{< /code >}} + +## Menu entry parameters + +When you define menu entries [in site configuration] or [in front matter], you can include a `params` key as shown in these examples: + +- [Menu entry defined in site configuration] +- [Menu entry defined in front matter] + +This simplistic example renders a `class` attribute for each anchor element. Code defensively using `with` or `if` to handle entries where `params.class` is not defined. + +{{< code file=layouts/partials/menu.html >}} +{{- range site.Menus.main }} + + {{ .Name }} + +{{- end }} +{{< /code >}} + +## Localize + +Hugo provides two methods to localize your menu entries. See [multilingual]. + +[automatic]: /content-management/menus/#define-automatically +[define menu entries]: /content-management/menus/ +[defining menu entries]: /content-management/menus/ +[in front matter]: /content-management/menus/#define-in-front-matter +[in site configuration]: /content-management/menus/#define-in-site-configuration +[localize the menu entries]: /content-management/multilingual/#menus +[menu entry defined in front matter]: /content-management/menus/#example-front-matter +[menu entry defined in site configuration]: /content-management/menus/#example-site-configuration - [menu and methods]: /methods/menu/ ++[menu methods]: /methods/menu/ +[multilingual]: /content-management/multilingual/#menus diff --cc docs/content/en/templates/shortcode.md index 6d9234f71,000000000..5587c7479 mode 100644,000000..100644 --- a/docs/content/en/templates/shortcode.md +++ b/docs/content/en/templates/shortcode.md @@@ -1,405 -1,0 +1,422 @@@ +--- +title: Create your own shortcodes +linkTitle: Shortcode templates +description: You can extend Hugo's embedded shortcodes by creating your own using the same templating syntax as that for single and list pages. +categories: [templates] +keywords: [] +menu: + docs: + parent: templates + weight: 130 +weight: 130 +aliases: [/templates/shortcode-templates/] +toc: true +--- + +Shortcodes are a means to consolidate templating into small, reusable snippets that you can embed directly inside your content. + +{{% note %}} +Hugo also ships with embedded shortcodes for common use cases. (See [Content Management: Shortcodes](/content-management/shortcodes/).) +{{% /note %}} + +## Create custom shortcodes + +Hugo's embedded shortcodes cover many common, but not all, use cases. Luckily, Hugo provides the ability to easily create custom shortcodes to meet your website's needs. + +{{< youtube Eu4zSaKOY4A >}} + +### File location + +To create a shortcode, place an HTML template in the `layouts/shortcodes` directory. Consider the file name carefully since the shortcode name will mirror that of the file but without the `.html` extension. For example, `layouts/shortcodes/myshortcode.html` will be called with either `{{}}` or `{{%/* myshortcode /*/%}}`. + +You can organize your shortcodes in subdirectories, e.g. in `layouts/shortcodes/boxes`. These shortcodes would then be accessible with their relative path, e.g: + +```go-html-template +{{}} +``` + +Note the forward slash. + - ### Shortcode template lookup order - - Shortcode templates have a simple [lookup order]: - - 1. `/layouts/shortcodes/.html` - 2. `/themes//layouts/shortcodes/.html` ++### Template 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|rss|en|layouts/shortcodes/foo.en.xml ++foo|rss|en|layouts/shortcodes/foo.rss.xml ++foo|rss|en|layouts/shortcodes/foo.en.html ++foo|rss|en|layouts/shortcodes/foo.rss.en.xml ++foo|rss|en|layouts/shortcodes/foo.xml ++foo|rss|en|layouts/shortcodes/foo.html.en.html ++foo|rss|en|layouts/shortcodes/foo.html.html ++foo|rss|en|layouts/shortcodes/foo.html ++ ++Note that templates provided by a theme or module always take precedence. + +### Positional vs. named arguments + +You can create shortcodes using the following types of arguments: + +* Positional arguments +* Named arguments +* Positional *or* named arguments + +In shortcodes with positional arguments, the order of the arguments is important. If a shortcode has a single required value, positional arguments require less typing from content authors. + +For more complex layouts with multiple or optional arguments, named arguments work best. While less terse, named arguments require less memorization from a content author and can be added in a shortcode declaration in any order. + +Allowing both types of arguments is useful for complex layouts where you want to set default values that can be easily overridden by users. + +### Access arguments + +All shortcode arguments can be accessed via the `.Get` method. Whether you pass a string or a number to the `.Get` method depends on whether you are accessing a named or positional argument, respectively. + +To access an argument by name, use the `.Get` method followed by the named argument as a quoted string: + +```go-html-template +{{ .Get "class" }} +``` + +To access an argument by position, use the `.Get` followed by a numeric position, keeping in mind that positional arguments are zero-indexed: + +```go-html-template +{{ .Get 0 }} +``` + +For the second position, you would just use: + +```go-html-template +{{ .Get 1 }} +``` + +`with` is great when the output depends on a argument being set: + +```go-html-template +{{ with .Get "class" }} class="{{ . }}"{{ end }} +``` + +`.Get` can also be used to check if a argument has been provided. This is +most helpful when the condition depends on either of the values, or both: + +```go-html-template +{{ if or (.Get "title") (.Get "alt") }} alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "title" }}{{ end }}"{{ end }} +``` + +#### `.Inner` + +The `.Inner` method returns the content between the opening and closing shortcode tags. To check if `.Inner` returns anything other than whitespace: + +```go-html-template +{{ if strings.ContainsNonSpace .Inner }} + Inner is not empty +{{ end }} +``` + +{{% note %}} +Any shortcode that calls the `.Inner` method must be closed or self-closed. To call a shortcode using the self-closing syntax. + +```go-html-template +{{}} +``` + +{{% /note %}} + +#### `.Params` + +The `.Params` method in shortcodes returns the arguments passed to the shortcode for more complicated use cases. You can also access higher-scoped arguments with the following logic: + +$.Params +: these are the arguments passed directly into the shortcode declaration (e.g., a YouTube video ID) + +$.Page.Params +: refers to the page's parameters; the "page" in this case refers to the content file in which the shortcode is declared (e.g., a `shortcode_color` field in a content's front matter could be accessed via `$.Page.Params.shortcode_color`). + +$.Site.Params +: refers to parameters defined in your site configuration. + +#### `.IsNamedParams` + +The `.IsNamedParams` method checks whether the shortcode declaration uses named arguments and returns a boolean value. + +For example, you could create an `image` shortcode that can take either a `src` named argument or the first positional argument, depending on the preference of the content's author. Let's assume the `image` shortcode is called as follows: + +```go-html-template +{{}} +``` + +You could then include the following as part of your shortcode templating: + +```go-html-template +{{ if .IsNamedParams }} + +{{ else }} + +{{ end }} +``` + +See the [example Vimeo shortcode][vimeoexample] below for `.IsNamedParams` in action. + +{{% note %}} +While you can create shortcode templates that accept both positional and named arguments, you *cannot* declare shortcodes in content with a mix of argument types. Therefore, a shortcode declared like `{{}}` will return an error. +{{% /note %}} + +Shortcodes can also be nested. In a nested shortcode, you can access the parent shortcode context with the [`.Parent`] shortcode method. This can be very useful for inheritance from the root. + +### Checking for existence + +You can check if a specific shortcode is used on a page by calling `.HasShortcode` in that page template, providing the name of the shortcode. This is useful when you want to include specific scripts or styles in the header that are only used by that shortcode. + +## Custom shortcode examples + +The following are examples of the different types of shortcodes you can create via shortcode template files in `/layouts/shortcodes`. + +### Single-word example: `year` + +Let's assume you would like to keep mentions of your copyright year current in your content files without having to continually review your Markdown. Your goal is to be able to call the shortcode as follows: + +```go-html-template +{{}} +``` + +{{< code file=layouts/shortcodes/year.html >}} +{{ now.Format "2006" }} +{{< /code >}} + +### Single positional example: `youtube` + +Embedded videos are a common addition to Markdown content. The following is the code used by [Hugo's built-in YouTube shortcode][youtubeshortcode]: + +```go-html-template +{{}} +``` + +Would load the template at `/layouts/shortcodes/youtube.html`: + +{{< code file=layouts/shortcodes/youtube.html >}} +
    + +
    +{{< /code >}} + +{{< code file=youtube-embed.html >}} +
    + +
    +{{< /code >}} + +### Single named example: `image` + +Let's say you want to create your own `img` shortcode rather than use Hugo's built-in [`figure` shortcode][figure]. Your goal is to be able to call the shortcode as follows in your content files: + +{{< code file=content-image.md >}} +{{}} +{{< /code >}} + +You have created the shortcode at `/layouts/shortcodes/img.html`, which loads the following shortcode template: + +{{< code file=layouts/shortcodes/img.html >}} + +
    + {{ with .Get "link" }}{{ end }} + + {{ if .Get "link" }}{{ end }} + {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr") }} +
    {{ if isset .Params "title" }} +

    {{ .Get "title" }}

    {{ end }} + {{ if or (.Get "caption") (.Get "attr") }}

    + {{ .Get "caption" }} + {{ with .Get "attrlink" }} {{ end }} + {{ .Get "attr" }} + {{ if .Get "attrlink" }} {{ end }} +

    {{ end }} +
    + {{ end }} +
    + +{{< /code >}} + +Would be rendered as: + +{{< code file=img-output.html >}} +
    + +
    +

    Steve Francia

    +
    +
    +{{< /code >}} + +### Single flexible example: `vimeo` + +```go-html-template +{{}} +{{}} +``` + +Would load the template found at `/layouts/shortcodes/vimeo.html`: + +{{< code file=layouts/shortcodes/vimeo.html >}} +{{ if .IsNamedParams }} +
    + +
    +{{ else }} +
    + +
    +{{ end }} +{{< /code >}} + +Would be rendered as: + +{{< code file=vimeo-iframes.html >}} +
    + +
    +
    + +
    +{{< /code >}} + +### Paired example: `highlight` + +The following is taken from `highlight`, which is a [built-in shortcode] that ships with Hugo. + +{{< code file=highlight-example.md >}} +{{}} + + This HTML + +{{}} +{{< /code >}} + +The template for the `highlight` shortcode uses the following code, which is already included in Hugo: + +```go-html-template +{{ .Get 0 | highlight .Inner }} +``` + +The rendered output of the HTML example code block will be as follows: + +{{< code file=syntax-highlighted.html >}} +
    <html>
     +    <body> This HTML </body>
     +</html>
     +
    +{{< /code >}} + +### Nested shortcode: image gallery + +Hugo's [`.Parent`] shortcode 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: + +{{< code file=layouts/shortcodes/gallery.html >}} +
    + {{ .Inner }} +
    +{{< /code >}} + +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`: + +{{< code file=layouts/shortcodes/img.html >}} +{{- $src := .Get "src" -}} +{{- with .Parent -}} + +{{- else -}} + +{{- end -}} +{{< /code >}} + +You can then call your shortcode in your content as follows: + +```go-html-template +{{}} + {{}} + {{}} +{{}} +{{}} +``` + +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 + + +``` + +## Error handling in shortcodes + +Use the [`errorf`] template function with the [`Name`] and [`Position`] shortcode methods to generate useful error messages: + +{{< code file=layouts/shortcodes/greeting.html >}} +{{ with .Get "name" }} +

    Hello, my name is {{ . }}.

    +{{ else }} + {{ errorf "The %q shortcode requires a 'name' argument. See %s" .Name .Position }} +{{ end }} +{{< /code >}} + +When the above fails, you will see an `ERROR` message such as: + +```sh +ERROR The "greeting" shortcode requires a 'name' argument. See "/home/user/project/content/_index.md:12:1" +``` + +## Inline shortcodes + +You can also implement your shortcodes inline -- e.g. where you use them in the content file. This can be useful for scripting that you only need in one place. + +This feature is disabled by default, but can be enabled in your site configuration: + +{{< code-toggle file=hugo >}} +[security] +enableInlineShortcodes = true +{{< /code-toggle >}} + +It is disabled by default for security reasons. The security model used by Hugo's template handling assumes that template authors are trusted, but that the content files are not, so the templates are injection-safe from malformed input data. But in most situations you have full control over the content, too, and then `enableInlineShortcodes = true` would be considered safe. But it's something to be aware of: It allows ad-hoc [Go Text templates](https://golang.org/pkg/text/template/) to be executed from the content files. + +And once enabled, you can do this in your content files: + + ```go-html-template + {{}}{{ now }}{{}} + ``` + +The above will print the current date and time. + +Note that an inline shortcode's inner content is parsed and executed as a Go text template with the same context as a regular shortcode template. + +This means that the current page can be accessed via `.Page.Title` etc. This also means that there are no concept of "nested inline shortcodes". + +The same inline shortcode can be reused later in the same content file, with different arguments if needed, using the self-closing syntax: + + ```go-html-template +{{}} +``` + +[`.Parent`]: /methods/shortcode/parent/ +[`errorf`]: /functions/fmt/errorf/ +[`Name`]: /methods/shortcode/name/ +[`Position`]: /methods/shortcode/position/ +[built-in shortcode]: /content-management/shortcodes/ +[figure]: /content-management/shortcodes/#figure +[lookup order]: /templates/lookup-order/ +[source organization]: /getting-started/directory-structure/ +[vimeoexample]: #single-flexible-example-vimeo +[youtubeshortcode]: /content-management/shortcodes/#youtube diff --cc docs/content/en/tools/migrations.md index 3a2cdac35,000000000..99064e271 mode 100644,000000..100644 --- a/docs/content/en/tools/migrations.md +++ b/docs/content/en/tools/migrations.md @@@ -1,105 -1,0 +1,105 @@@ +--- +title: Migrate to Hugo +linkTitle: Migrations +description: A list of community-developed tools for migrating from your existing static site generator or content management system to Hugo. +categories: [developer tools] +keywords: [migrations,jekyll,wordpress,drupal,ghost,contentful] +menu: + docs: + parent: developer-tools + weight: 50 +weight: 50 +toc: true +aliases: [/developer-tools/migrations/, /developer-tools/migrated/] +--- + - This section highlights some projects around Hugo that are independently developed. These tools try to extend the functionality of our static site generator or help you to get started. ++This section highlights some independently developed projects related to Hugo. These tools extend functionality or help you to get started. + - Take a look at this list of migration tools if you currently use other blogging tools like Jekyll or WordPress but intend to switch to Hugo instead. They'll take care to export your content into Hugo-friendly formats. ++Take a look at this list of migration tools if you currently use other blogging tools like Jekyll or WordPress but intend to switch to Hugo instead. They'll help you export your content into Hugo-friendly formats. + +## Jekyll + +Alternatively, you can use the [Jekyll import command](/commands/hugo_import_jekyll/). + +[JekyllToHugo](https://github.com/fredrikloch/JekyllToHugo) +: A Small script for converting Jekyll blog posts to a Hugo site. + +[ConvertToHugo](https://github.com/coderzh/ConvertToHugo) +: Convert your blog from Jekyll to Hugo. + +## Octopress + +[octohug](https://github.com/codebrane/octohug) +: Octopress to Hugo migrator. + +## DokuWiki + +[dokuwiki-to-hugo](https://github.com/wgroeneveld/dokuwiki-to-hugo) - : Migrates your DokuWiki source pages from [DokuWiki syntax](https://www.dokuwiki.org/wiki:syntax) to Hugo Markdown syntax. Includes extra's like the TODO plugin. Written with extensibility in mind using python 3. Also generates a TOML header for each page. Designed to copypaste the wiki directory into your /content directory. ++: Migrates your DokuWiki source pages from [DokuWiki syntax](https://www.dokuwiki.org/wiki:syntax) to Hugo Markdown syntax. Includes extras like the TODO plugin. Written with extensibility in mind using Python 3. Also generates a TOML header for each page. Designed to copy-paste the wiki directory into your /content directory. + +## WordPress + +[wordpress-to-hugo-exporter](https://github.com/SchumacherFM/wordpress-to-hugo-exporter) - : A one-click WordPress plugin that converts all posts, pages, taxonomies, metadata, and settings to Markdown and YAML which can be dropped into Hugo. (Note: If you have trouble using this plugin, you can [export your site for Jekyll](https://wordpress.org/plugins/jekyll-exporter/) and use Hugo's built in Jekyll converter listed above.) ++: A one-click WordPress plugin that converts all posts, pages, taxonomies, metadata, and settings to Markdown and YAML which can be dropped into Hugo. (Note: If you have trouble using this plugin, you can [export your site for Jekyll](https://wordpress.org/plugins/jekyll-exporter/) and use Hugo's built-in Jekyll converter listed above.) + +[blog2md](https://github.com/palaniraja/blog2md) +: Works with [exported xml](https://en.support.wordpress.com/export/) file of your free YOUR-TLD.wordpress.com website. It also saves approved comments to `YOUR-POST-NAME-comments.md` file along with posts. + +[wordhugopress](https://github.com/nantipov/wordhugopress) - : A small utility written in Java, exports the entire WordPress site from the database and resource (e.g. images) files stored locally or remotely. Therefore, migration from the backup files is possible. Supports merging of the multiple WordPress sites into a single Hugo one. ++: A small utility written in Java that exports the entire WordPress site from the database and resource (e.g., images) files stored locally or remotely. Therefore, migration from the backup files is possible. Supports merging multiple WordPress sites into a single Hugo site. + +[wp2hugo](https://github.com/ashishb/wp2hugo) +: A Go-based CLI tool to migrate WordPress website to Hugo while preserving original URLs, GUIDs (for feeds), image URLs, code highlights, table of contents, YouTube embeds, Google Maps embeds, and original WordPress navigation categories. + +## Medium + +[medium2md](https://github.com/gautamdhameja/medium-2-md) +: A simple Medium to Hugo exporter able to import stories in one command, including front matter. + +[medium-to-hugo](https://github.com/bgadrian/medium-to-hugo) - : CLI tool written in Go to export medium posts into a Hugo compatible Markdown format. Tags and images are included. All images will be downloaded locally and linked appropriately. ++: A CLI tool written in Go to export medium posts into a Hugo-compatible Markdown format. Tags and images are included. All images will be downloaded locally and linked appropriately. + +## Tumblr + +[tumblr-importr](https://github.com/carlmjohnson/tumblr-importr) +: An importer that uses the Tumblr API to create a Hugo static site. + +[tumblr2hugomarkdown](https://github.com/Wysie/tumblr2hugomarkdown) +: Export all your Tumblr content to Hugo Markdown files with preserved original formatting. + +[Tumblr to Hugo](https://github.com/jipiboily/tumblr-to-hugo) - : A migration tool that converts each of your Tumblr posts to a content file with a proper title and path. Furthermore, "Tumblr to Hugo" creates a CSV file with the original URL and the new path on Hugo, to help you setup the redirections. ++: A migration tool that converts each of your Tumblr posts to a content file with a proper title and path. It also generates a CSV file to help you set up URL redirects. + +## Drupal + +[drupal2hugo](https://github.com/danapsimer/drupal2hugo) +: Convert a Drupal site to Hugo. + +## Joomla + +[hugojoomla](https://github.com/davetcc/hugojoomla) +: This utility written in Java takes a Joomla database and converts all the content into Markdown files. It changes any URLs that are in Joomla's internal format and converts them to a suitable form. + +## Blogger + +[blogimport](https://github.com/natefinch/blogimport) +: A tool to import from Blogger posts to Hugo. + +[blogger-to-hugo](https://pypi.org/project/blogger-to-hugo/) +: Another tool to import Blogger posts to Hugo. It also downloads embedded images so they will be stored locally. + +[blog2md](https://github.com/palaniraja/blog2md) +: Works with [exported xml](https://support.google.com/blogger/answer/41387?hl=en) file of your YOUR-TLD.blogspot.com website. It also saves comments to `YOUR-POST-NAME-comments.md` file along with posts. + +[BloggerToHugo](https://github.com/huanlin/blogger-to-hugo) +: Yet another tool to import Blogger posts to Hugo. For Windows platform only, and .NET Framework 4.5 is required. See README.md before using this tool. + +## Contentful + +[contentful-hugo](https://github.com/ModiiMedia/contentful-hugo) +: A tool to create content-files for Hugo from content on [Contentful](https://www.contentful.com/). + +## BlogML + +[BlogML2Hugo](https://github.com/jijiechen/BlogML2Hugo) +: A tool that helps you convert BlogML xml file to Hugo Markdown files. Users need to take care of links to attachments and images by themselves. This helps the blogs that export BlogML files (e.g. BlogEngine.NET) transform to hugo sites easily. diff --cc docs/content/en/tools/search.md index 921d52f82,000000000..614bc511c mode 100644,000000..100644 --- a/docs/content/en/tools/search.md +++ b/docs/content/en/tools/search.md @@@ -1,55 -1,0 +1,59 @@@ +--- +title: Search tools +linkTitle: Search +description: See some of the open-source and commercial search options for your newly created Hugo website. +categories: [developer tools] +keywords: [search] +menu: + docs: + parent: developer-tools + weight: 40 +weight: 40 +toc: true +--- + +A static website with a dynamic search function? Yes, Hugo provides an alternative to embeddable scripts from Google or other search engines for static websites. Hugo allows you to provide your visitors with a custom search function by indexing your content files directly. + +## Open-source + +[Pagefind](https://github.com/cloudcannon/pagefind) +: A fully static search library that aims to perform well on large sites, while using as little of your users' bandwidth as possible. + +[GitHub Gist for Hugo Workflow](https://gist.github.com/sebz/efddfc8fdcb6b480f567) +: This gist contains a simple workflow to create a search index for your static website. It uses a simple Grunt script to index all your content files and [lunr.js](https://lunrjs.com/) to serve the search results. + +[hugo-lunr](https://www.npmjs.com/package/hugo-lunr) +: A simple way to add site search to your static Hugo site using [lunr.js](https://lunrjs.com/). Hugo-lunr will create an index file of any HTML and Markdown documents in your Hugo project. + +[hugo-lunr-zh](https://www.npmjs.com/package/hugo-lunr-zh) +: A bit like Hugo-lunr, but Hugo-lunr-zh can help you separate the Chinese keywords. + +[GitHub Gist for Fuse.js integration](https://gist.github.com/eddiewebb/735feb48f50f0ddd65ae5606a1cb41ae) +: This gist demonstrates how to leverage Hugo's existing build time processing to generate a searchable JSON index used by [Fuse.js](https://fusejs.io/) on the client-side. Although this gist uses Fuse.js for fuzzy matching, any client-side search tool capable of reading JSON indexes will work. Does not require npm, grunt, or other build-time tools except Hugo! + +[hugo-search-index](https://www.npmjs.com/package/hugo-search-index) +: A library containing Gulp tasks and a prebuilt browser script that implements search. Gulp generates a search index from project Markdown files. + +[hugofastsearch](https://gist.github.com/cmod/5410eae147e4318164258742dd053993) +: A usability and speed update to "GitHub Gist for Fuse.js integration" — global, keyboard-optimized search. + +[JS & Fuse.js tutorial](https://makewithhugo.com/add-search-to-a-hugo-site/) +: A simple client-side search solution, using FuseJS (does not require jQuery). + +[Hugo Lyra](https://github.com/paolomainardi/hugo-lyra) +: Hugo-Lyra is a JavaScript module to integrate [Lyra](https://github.com/LyraSearch/lyra) into a Hugo website. It contains the server-side part to generate the index and the client-side library (optional) to bootstrap the search engine easily. + ++[INFINI Pizza for WebAssembly](https://github.com/infinilabs/pizza-docsearch) ++: Pizza is a super-lightweight yet fully featured search engine written in Rust. You can quickly add offline search functionality to your Hugo website in just five minutes with only three lines of code. For a step-by-step guide on integrating it with Hugo, check out [this blog tutorial](https://dev.to/medcl/adding-search-functionality-to-a-hugo-static-site-based-on-infini-pizza-for-webassembly-4h5e). ++ ++ +## Commercial + +[Algolia](https://www.algolia.com/) +: Algolia's Search API makes it easy to deliver a great search experience in your apps and websites. Algolia Search provides hosted full-text, numerical, faceted, and geolocalized search. + +[Bonsai](https://www.bonsai.io) +: Bonsai is a fully-managed hosted Elasticsearch service that is fast, reliable, and simple to set up. Easily ingest your docs from Hugo into Elasticsearch following [this guide from the docs](https://bonsai.io/docs/hugo). + +[ExpertRec](https://www.expertrec.com/) +: ExpertRec is a hosted search-as-a-service solution that is fast and scalable. Set-up and integration is extremely easy and takes only a few minutes. The search settings can be modified without coding using a dashboard. diff --cc docs/go.mod index 51d5f3a43,000000000..7fd269069 mode 100644,000000..100644 --- a/docs/go.mod +++ b/docs/go.mod @@@ -1,5 -1,0 +1,5 @@@ +module github.com/gohugoio/hugoDocs + +go 1.16 + - require github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472 // indirect ++require github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f // indirect diff --cc docs/go.sum index 633446af0,000000000..4e5e32477 mode 100644,000000..100644 --- a/docs/go.sum +++ b/docs/go.sum @@@ -1,12 -1,0 +1,16 @@@ +github.com/gohugoio/gohugoioTheme v0.0.0-20240426212330-f38e99e0d88d h1:EaFz80Aqh3Ej20VmUSNe3K+F0NbT8UueXLP/VqkK9Dw= +github.com/gohugoio/gohugoioTheme v0.0.0-20240426212330-f38e99e0d88d/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= +github.com/gohugoio/gohugoioTheme v0.0.0-20240508091825-b23e8e2d2419 h1:cQ/44eDHK0tVImTtSx/9sWWZv+RynH/oB4R7ASbQNAE= +github.com/gohugoio/gohugoioTheme v0.0.0-20240508091825-b23e8e2d2419/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= +github.com/gohugoio/gohugoioTheme v0.0.0-20240619093131-b595d5fb8c52 h1:dPJxUU4SevIZ7OS1DIVOrJ7p8I/QM00pXGRfAtKgQmU= +github.com/gohugoio/gohugoioTheme v0.0.0-20240619093131-b595d5fb8c52/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= +github.com/gohugoio/gohugoioTheme v0.0.0-20240622143740-53a4bdb8c0fb h1:gOIE1eFXILxCio/QOm3oLYcYmsis2CD099dXbXpjprA= +github.com/gohugoio/gohugoioTheme v0.0.0-20240622143740-53a4bdb8c0fb/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= +github.com/gohugoio/gohugoioTheme v0.0.0-20240623150114-cc7096eab3fd h1:I8X7c0oBRWXy83BL2ODSk7v0xPXDnp2hcFWpCcN+Kyc= +github.com/gohugoio/gohugoioTheme v0.0.0-20240623150114-cc7096eab3fd/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= +github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472 h1:AYZUibKKFRBp2VCQpDHW+JmQKvCvyhX7z7/SOLUSCcw= +github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= ++github.com/gohugoio/gohugoioTheme v0.0.0-20240812175901-cc0ef8e4a14a h1:E3JbZo69eqFBz6B+meQlKyy/ZBZQ73ldVDw8TADiIrQ= ++github.com/gohugoio/gohugoioTheme v0.0.0-20240812175901-cc0ef8e4a14a/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= ++github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f h1:Eo5z3uUYfmrtIxQvHm388dFOERZwWGTjLuUO6vobzLc= ++github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= diff --cc docs/hugo.toml index 63cc32798,000000000..2a271b6e3 mode 100644,000000..100644 --- a/docs/hugo.toml +++ b/docs/hugo.toml @@@ -1,100 -1,0 +1,102 @@@ +# This his the main configuration file. There are also environment specific configuration stored in the /config directory. + +baseURL = "https://gohugo.io/" +defaultContentLanguage = "en" +enableEmoji = true +ignoreErrors = ["error-remote-getjson", "error-missing-instagram-accesstoken"] +languageCode = "en-us" - paginate = 100 +pluralizeListTitles = false +timeZone = "Europe/Oslo" +title = "Hugo" + +# We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below). +disableAliases = true + ++[pagination] ++pagerSize = 100 ++ +[services.googleAnalytics] +ID = 'G-MBZGKNMDWC' + +[minify] + [minify.tdewolff] + [minify.tdewolff.html] + keepWhitespace = true + +[module] + [module.hugoVersion] + min = "0.56.0" + [[module.imports]] + path = "github.com/gohugoio/gohugoioTheme" + +[outputs] + home = ["HTML", "RSS", "REDIR", "HEADERS"] + section = ["HTML"] + +[mediaTypes] + [mediaTypes."text/netlify"] + delimiter = "" + +[outputFormats] + [outputFormats.REDIR] + mediatype = "text/netlify" + baseName = "_redirects" + isPlainText = true + notAlternative = true + [outputFormats.HEADERS] + mediatype = "text/netlify" + baseName = "_headers" + isPlainText = true + notAlternative = true + +[caches] + [caches.getjson] + dir = ":cacheDir/:project" + maxAge = -1 + [caches.getcsv] + dir = ":cacheDir/:project" + maxAge = -1 + [caches.images] + dir = ":cacheDir/images" + maxAge = "1440h" + [caches.assets] + dir = ":resourceDir/_gen" + maxAge = -1 + [caches.getresource] + dir = ":cacheDir/:project" + maxage = '1h' + +[related] + threshold = 80 + includeNewer = true + toLower = false + [[related.indices]] + name = "keywords" + weight = 60 + [[related.indices]] + # Can be used as a front matter slice to link to other page fragments (headings) using their ID. + # This isn't particular useful in the current docs, but we're planning on getting a auto generated + # reference section with a better ID setup. + # For now, we just use it to give pages with same headings some similarity score. + name = "fragmentrefs" + type = "fragments" + applyFilter = false + weight = 60 + cardinalityThreshold = 50 + +[imaging] + # See https://github.com/disintegration/imaging + # CatmullRom is a sharp bicubic filter which should fit the docs site well with its many screenshots. + # Note that you can also set this per image processing. + resampleFilter = "CatmullRom" + # Default JPEG quality setting. Default is 75. + quality = 75 + anchor = "smart" + +[taxonomies] + category = "categories" + +[[cascade]] +categories = ['commands'] +[cascade._target] +path = '/commands/**' diff --cc docs/netlify.toml index f7f1a5f04,000000000..44c10a3c9 mode 100644,000000..100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@@ -1,30 -1,0 +1,30 @@@ +[build] + publish = "public" + command = "hugo --gc --minify" + + [build.environment] - HUGO_VERSION = "0.131.0" ++ HUGO_VERSION = "0.133.1" + +[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" + +[context.branch-deploy] + command = "hugo --gc --minify -b $DEPLOY_PRIME_URL" + +[context.next.environment] + HUGO_ENABLEGITINFO = "true" + +[[redirects]] + from = "/npmjs/*" + to = "/npmjs/" + status = 200