From: Bjørn Erik Pedersen Date: Mon, 7 Aug 2023 08:38:12 +0000 (+0200) Subject: Merge commit '7c62d6ef1654c0383eae474d3bd9ddf7754c1f30' X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=5d5fb22ead440e118030e3440c4dc748fda9bf75;p=brevno-suite%2Fhugo Merge commit '7c62d6ef1654c0383eae474d3bd9ddf7754c1f30' --- 5d5fb22ead440e118030e3440c4dc748fda9bf75 diff --cc docs/config/_default/security.toml index 2be3f1ba8,000000000..8bd91945f mode 100644,000000..100644 --- a/docs/config/_default/security.toml +++ b/docs/config/_default/security.toml @@@ -1,13 -1,0 +1,9 @@@ + + enableInlineShortcodes = false + - [exec] - allow = ['^go$'] - osEnv = ['^PATH$'] - + [funcs] + getenv = ['^HUGO_', '^REPOSITORY_URL$', '^BRANCH$'] + + [http] + methods = ['(?i)GET|POST'] + urls = ['.*'] diff --cc docs/content/en/content-management/multilingual.md index 4c1f6446e,000000000..849df681f mode 100644,000000..100644 --- a/docs/content/en/content-management/multilingual.md +++ b/docs/content/en/content-management/multilingual.md @@@ -1,674 -1,0 +1,674 @@@ +--- +title: Multilingual mode +linkTitle: Multilingual +description: Hugo supports the creation of websites with multiple languages side by side. +categories: [content management] +keywords: [multilingual,i18n, internationalization] +menu: + docs: + parent: content-management + weight: 230 +toc: true +weight: 230 +aliases: [/content/multilingual/,/tutorials/create-a-multilingual-site/] +--- + +You should define the available languages in a `languages` section in your site configuration. + +Also See [Hugo Multilingual Part 1: Content translation]. + +## Configure languages + +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 tag as defined by [RFC 5646]. Must be lower case, and must match one of the defined language keys. Default is `en`. 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 defined by [RFC 5646]. This value may include upper and lower case characters, hyphens or underscores, and 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 language title. When set, this overrides the site title for this language. + +`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 +[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, add all of these below `[params]`, see `color` in the example below. + +```toml +title = "My blog" +languageCode = "en-us" + +[languages] +[languages.sv] +title = "Min blogg" +languageCode = "sv" +[languages.en.params] +color = "blue" +``` + +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" copy=false >}} +[languages.es] +disabled = true +{{< /code-toggle >}} + +To disable one or more languages in the root of your site configuration: + +{{< code-toggle file="hugo" copy=false >}} +disableLanguages = ["es", "fr"] +{{< /code-toggle >}} + +To disable one or more languages using an environment variable: + +```bash +HUGO_DISABLELANGUAGES="es fr" hugo +``` + +Note that you cannot disable the default content language. + +### Configure multilingual multihost + +From **Hugo 0.31** we support multiple languages in a multihost configuration. See [this issue](https://github.com/gohugoio/hugo/issues/4027) for details. + +This means that you can now 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.fr] +baseURL = "https://example.fr" +languageName = "Français" +weight = 1 +title = "En Français" + +[languages.en] +baseURL = "https://example.com" +languageName = "English" +weight = 2 +title = "In English" +{{}} + +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.com/`.** + +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) +Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1) +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 copy=false >}} +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, whether a [single content page][contenttemplate] or the [homepage]. 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 + +Hugo uses [go-i18n] to support string translations. [See the project's source repository][go-i18n-source] to find tools that will help you manage your translation workflows. + +Translations are collected from the `themes//i18n/` folder (built into the theme), as well as translations present in `i18n/` at the root of your project. In the `i18n`, the translations will be merged and take precedence over what is in the theme folder. Language files should be named according to [RFC 5646] with names such as `en-US.toml`, `fr.toml`, etc. + +Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7](https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7) are also supported. You may omit the `art-x-` prefix for brevity. For example: + +```text +art-x-hugolang +hugolang +``` + +Private use subtags must not exceed 8 alphanumeric characters. + +### Query basic translation + +From within your templates, use the `i18n` function like this: + +```go-html-template +{{ i18n "home" }} +``` + +The function will search for the `"home"` id: + +{{< code-toggle file="i18n/en-US" >}} +[home] +other = "Home" +{{< /code-toggle >}} + +The result will be + +```text +Home +``` + +### Query a flexible translation with variables + +Often you will want to use the page variables in the translation strings. To do so, pass the `.` context when calling `i18n`: + +```go-html-template +{{ i18n "wordCount" . }} +``` + +The function will pass the `.` context to the `"wordCount"` id: + +{{< code-toggle file="i18n/en-US" >}} +[wordCount] +other = "This article has {{ .WordCount }} words." +{{< /code-toggle >}} + +Assume `.WordCount` in the context has value is 101. The result will be: + +```text +This article has 101 words. +``` + +### Query a singular/plural translation + +In other to meet singular/plural requirement, you must pass a dictionary (map) with a numeric `.Count` property to the `i18n` function. The below example uses `.ReadingTime` variable which has a built-in `.Count` property. + +```go-html-template +{{ i18n "readingTime" .ReadingTime }} +``` + +The function will read `.Count` from `.ReadingTime` and evaluate whether the number is singular (`one`) or plural (`other`). After that, it will pass to `readingTime` id in `i18n/en-US.toml` file: + +{{< code-toggle file="i18n/en-US" >}} +[readingTime] +one = "One minute to read" +other = "{{ .Count }} minutes to read" +{{< /code-toggle >}} + +Assuming `.ReadingTime.Count` in the context has value is 525600. The result will be: + +```text +525600 minutes to read +``` + +If `.ReadingTime.Count` in the context has value is 1. The result is: + +```text +One minute to read +``` + +In case you need to pass a custom data: (`(dict "Count" numeric_value_only)` is minimum requirement) + +```go-html-template +{{ i18n "readingTime" (dict "Count" 25 "FirstArgument" true "SecondArgument" false "Etc" "so on, so far") }} +``` + +## 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 }} ---> 512.50% ++{{ 512.5032 | lang.FormatPercent 2 }} → 512.50% +``` + +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 the 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 can (a) use translation tables, or (b) create language-specific menu entries under each language key. + +### 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" copy=false >}} +[[menu.main]] + identifier = 'products' + name = 'Products' + pageRef = '/products' + weight = 10 +[[menu.main]] + identifier = 'services' + name = 'Services' + pageRef = '/services' + weight = 20 +{{< / code-toggle >}} + +Create corresponding entries in the translation tables: + +{{< code-toggle file="i18n/de" copy=false >}} +products = 'Produkte' +services = 'Leistungen' +{{< / code-toggle >}} + +[example menu template]: /templates/menu-templates/#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 + +### Create language-specific menu entries + +For example: + +{{< code-toggle file="hugo" copy=false >}} +[languages.de] +languageCode = 'de-DE' +languageName = 'Deutsch' +weight = 1 + +[[languages.de.menu.main]] +name = 'Produkte' +pageRef = '/products' +weight = 10 + +[[languages.de.menu.main]] +name = 'Leistungen' +pageRef = '/services' +weight = 20 + +[languages.en] +languageCode = 'en-US' +languageName = 'English' +weight = 2 + +[[languages.en.menu.main]] +name = 'Products' +pageRef = '/products' +weight = 10 + +[[languages.en.menu.main]] +name = 'Services' +pageRef = '/services' +weight = 20 +{{< /code-toggle >}} + +For a simple menu with two languages, these menu entries are easy to create and maintain. For a larger menu, or with more than two languages, using translation tables as described above is preferable. + +## 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: + +```bash +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` template function][rellangurl] or the [`absLangURL` template function][abslangurl] **OR** be prefixed with `{{ .LanguagePrefix }}` + +If there is more than one language defined, the `LanguagePrefix` variable will equal `/en` (or whatever your `CurrentLanguage` 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` + +If you organize content with translations in the same directory: + +```text +hugo new post/test.en.md +hugo new post/test.de.md +``` + +If you organize content with translations in different directories: + +```text +hugo new content/en/post/test.md +hugo new content/de/post/test.md +``` + +[abslangurl]: /functions/abslangurl +[config]: /getting-started/configuration/ +[contenttemplate]: /templates/single-page-templates/ +[go-i18n-source]: https://github.com/nicksnyder/go-i18n +[go-i18n]: https://github.com/nicksnyder/go-i18n +[homepage]: /templates/homepage/ +[Hugo Multilingual Part 1: Content translation]: https://regisphilibert.com/blog/2018/08/hugo-multilingual-part-1-managing-content-translation/ +[i18func]: /functions/i18n/ +[lang.FormatAccounting]: /functions/lang +[lang.FormatCurrency]: /functions/lang +[lang.FormatNumber]: /functions/lang +[lang.FormatNumberCustom]: /functions/lang +[lang.FormatPercent]: /functions/lang +[lang.Merge]: /functions/lang.merge/ +[menus]: /content-management/menus/ +[OS environment]: /getting-started/configuration/#configure-with-environment-variables +[rellangurl]: /functions/rellangurl +[RFC 5646]: https://tools.ietf.org/html/rfc5646 +[single page templates]: /templates/single-page-templates/ +[time.Format]: /functions/dateformat diff --cc docs/content/en/content-management/summaries.md index 4f94f95f2,000000000..74c5623cb mode 100644,000000..100644 --- a/docs/content/en/content-management/summaries.md +++ b/docs/content/en/content-management/summaries.md @@@ -1,108 -1,0 +1,108 @@@ +--- +title: Content summaries +linkTitle: Summaries +description: Hugo generates summaries of your content. +categories: [content management] +keywords: [summaries,abstracts,read more] +menu: + docs: + parent: content-management + weight: 160 +toc: true +weight: 160 +aliases: [/content/summaries/,/content-management/content-summaries/] +--- + +With the use of the `.Summary` [page variable][pagevariables], Hugo generates summaries of content to use as a short version in summary views. + +## Summary splitting options + +* Automatic Summary Split +* Manual Summary Split +* Front Matter Summary + +It is natural to accompany the summary with links to the original content, and a common design pattern is to see this link in the form of a "Read More ..." button. See the `.RelPermalink`, `.Permalink`, and `.Truncated` [page variables][pagevariables]. + +### Automatic summary splitting + +By default, Hugo automatically takes the first 70 words of your content as its summary and stores it into the `.Summary` page variable for use in your templates. You may customize the summary length by setting `summaryLength` in your [site configuration](/getting-started/configuration/). + +{{% note %}} +You can customize how HTML tags in the summary are loaded using functions such as `plainify` and `safeHTML`. +{{% /note %}} + +{{% note %}} +The Hugo-defined summaries are set to use word count calculated by splitting the text by one or more consecutive whitespace characters. If you are creating content in a `CJK` language and want to use Hugo's automatic summary splitting, set `hasCJKLanguage` to `true` in your [site configuration](/getting-started/configuration/). +{{% /note %}} + +### Manual summary splitting + +Alternatively, you may add the <!--more--> summary divider where you want to split the article. + +For [Org mode content][org], use `# more` where you want to split the article. + +Content that comes before the summary divider will be used as that content's summary and stored in the `.Summary` page variable with all HTML formatting intact. + +{{% note %}} +The concept of a *summary divider* is not unique to Hugo. It is also called the "more tag" or "excerpt separator" in other literature. +{{% /note %}} + +Pros +: Freedom, precision, and improved rendering. All HTML tags and formatting are preserved. + +Cons +: Extra work for content authors, since they need to remember to type <!--more--> (or `# more` for [org content][org]) in each content file. This can be automated by adding the summary divider below the front matter of an [archetype](/content-management/archetypes/). + +{{% warning "Be Precise with the Summary Divider" %}} +Be careful to enter <!--more--> exactly; i.e., all lowercase and with no whitespace. +{{% /note %}} + +### Front matter summary + +You might want your summary to be something other than the text that starts the article. In this case you can provide a separate summary in the `summary` variable of the article front matter. + +Pros +: Complete freedom of text independent of the content of the article. Markup can be used within the summary. + +Cons +: Extra work for content authors as they need to write an entirely separate piece of text as the summary of the article. + +## Summary selection order + +Because there are multiple ways in which a summary can be specified it is useful to understand the order of selection Hugo follows when deciding on the text to be returned by `.Summary`. It is as follows: + +1. If there is a <!--more--> summary divider present in the article the text up to the divider will be provided as per the manual summary split method +2. If there is a `summary` variable in the article front matter the value of the variable will be provided as per the front matter summary method +3. The text at the start of the article will be provided as per the automatic summary split method + +{{% warning "Competing selections" %}} +Hugo uses the _first_ of the above steps that returns text. So if, for example, your article has both `summary` variable in its front matter and a <!--more--> summary divider Hugo will use the manual summary split method. +{{% /note %}} + +## Example: first 10 articles with summaries + +You can show content summaries with the following code. You could use the following snippet, for example, in a [section template]. + +{{< code file="page-list-with-summaries.html" >}} +{{ range first 10 .Pages }} - +{{ end }} +{{< /code >}} + +Note how the `.Truncated` boolean variable value may be used to hide the "Read More..." link when the content is not truncated; i.e., when the summary contains the entire article. + +[org]: /content-management/formats/ +[pagevariables]: /variables/page/ +[section template]: /templates/section-templates/ diff --cc docs/content/en/content-management/toc.md index e1f24378e,000000000..ca179c77d mode 100644,000000..100644 --- a/docs/content/en/content-management/toc.md +++ b/docs/content/en/content-management/toc.md @@@ -1,116 -1,0 +1,116 @@@ +--- +title: Table of contents +description: Hugo can automatically parse Markdown content and create a Table of Contents you can use in your templates. +categories: [content management] +keywords: [table of contents, toc] +menu: + docs: + parent: content-management + weight: 210 +toc: true +weight: 210 +aliases: [/extras/toc/] +--- + +{{% note %}} + +Previously, there was no out-of-the-box way to specify which heading levels you want the TOC to render. [See the related GitHub discussion (#1778)](https://github.com/gohugoio/hugo/issues/1778). As such, the resulting `` was going to start at `

` when pulling from `{{ .Content }}`. + +Hugo [v0.60.0](https://github.com/gohugoio/hugo/releases/tag/v0.60.0) made a switch to [Goldmark](https://github.com/yuin/goldmark/) as the default library for Markdown which has improved and configurable implementation of TOC. Take a look at [how to configure TOC](/getting-started/configuration-markup/#table-of-contents) for Goldmark renderer. + +{{% /note %}} + +## Usage + +Create your Markdown the way you normally would with the appropriate headings. Here is some example content: + +```md + + +## Introduction + +One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. + +## My Heading + +He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready to slide off any moment. + +### My Subheading + +A collection of textile samples lay spread out on the table - Samsa was a travelling salesman - and above it there hung a picture that he had recently cut out of an illustrated magazine and housed in a nice, gilded frame. It showed a lady fitted out with a fur hat and fur boa who sat upright, raising a heavy fur muff that covered the whole of her lower arm towards the viewer. Gregor then turned to look out the window at the dull weather. Drops +``` + +Hugo will take this Markdown and create a table of contents from `## Introduction`, `## My Heading`, and `### My Subheading` and then store it in the [page variable][pagevars]`.TableOfContents`. + +The built-in `.TableOfContents` variables outputs a `

` .Content }} +``` + +The `s` flag causes `.` to match `\n` as well, allowing us to find an `h2` element that contains newlines. + +To limit the number of matches to one: + +```go-html-template +{{ findRE `(?s).*?` .Content 1 }} +``` + +{{% note %}} +You can write and test your regular expression using [regex101.com](https://regex101.com/). Be sure to select the Go flavor before you begin. +{{% /note %}} diff --cc docs/content/en/functions/findresubmatch.md index e1085a9c9,000000000..1f0f26b49 mode 100644,000000..100644 --- a/docs/content/en/functions/findresubmatch.md +++ b/docs/content/en/functions/findresubmatch.md @@@ -1,102 -1,0 +1,88 @@@ +--- +title: findRESubmatch +description: Returns a slice of all successive matches of the regular expression. Each element is a slice of strings holding the text of the leftmost match of the regular expression and the matches, if any, of its subexpressions. +categories: [functions] +menu: + docs: + parent: functions +keywords: [regex] +signature: + - "findRESubmatch PATTERN INPUT [LIMIT]" + - "strings.FindRESubmatch PATTERN INPUT [LIMIT]" +relatedfuncs: [findRE, replaceRE] +--- + +By default, `findRESubmatch` finds all matches. You can limit the number of matches with an optional LIMIT parameter. A return value of nil indicates no match. + - When specifying the regular expression, use a raw [string literal] (backticks) instead of an interpreted string literal (double quotes) to simplify the syntax. With an interpreted string literal you must escape backslashes. - - [string literal]: https://go.dev/ref/spec#String_literals - - This function uses the [RE2] regular expression library. See the [RE2 syntax documentation] for details. Note that the RE2 `\C` escape sequence is not supported. - - [RE2]: https://github.com/google/re2/ - [RE2 syntax documentation]: https://github.com/google/re2/wiki/Syntax/ - - {{% note %}} - The RE2 syntax is a subset of that accepted by [PCRE], roughly speaking, and with various [caveats]. - - [caveats]: https://swtch.com/~rsc/regexp/regexp3.html#caveats - [PCRE]: https://www.pcre.org/ - {{% /note %}} ++{{% readfile file="/functions/common/regular-expressions.md" %}} + +## Demonstrative examples + +```go-html-template +{{ findRESubmatch `a(x*)b` "-ab-" }} → [["ab" ""]] +{{ findRESubmatch `a(x*)b` "-axxb-" }} → [["axxb" "xx"]] +{{ findRESubmatch `a(x*)b` "-ab-axb-" }} → [["ab" ""] ["axb" "x"]] +{{ findRESubmatch `a(x*)b` "-axxb-ab-" }} → [["axxb" "xx"] ["ab" ""]] +{{ findRESubmatch `a(x*)b` "-axxb-ab-" 1 }} → [["axxb" "xx"]] +``` + +## Practical example + +This markdown: + +```text +- [Example](https://example.org) +- [Hugo](https://gohugo.io) +``` + +Produces this HTML: + +```html + +``` + +To match the anchor elements, capturing the link destination and text: + +```go-html-template +{{ $regex := `(.+?)` }} +{{ $matches := findRESubmatch $regex .Content }} +``` + +Viewed as JSON, the data structure of `$matches` in the code above is: + +```json +[ + [ + "Example", + "https://example.org", + "Example" + ], + [ + "Hugo", + "https://gohugo.io", + "Hugo" + ] +] +``` + +To render the `href` attributes: + +```go-html-template +{{ range $matches }} + {{ index . 1 }} +{{ end }} +``` + +Result: + +```text +https://example.org +https://gohugo.io +``` + +{{% note %}} +You can write and test your regular expression using [regex101.com](https://regex101.com/). Be sure to select the Go flavor before you begin. +{{% /note %}} diff --cc docs/content/en/functions/getenv.md index e014b7ad5,000000000..daeeb6532 mode 100644,000000..100644 --- a/docs/content/en/functions/getenv.md +++ b/docs/content/en/functions/getenv.md @@@ -1,38 -1,0 +1,38 @@@ +--- +title: getenv +description: Returns the value of an environment variable, or an empty string if the environment variable is not set. +categories: [functions] +menu: + docs: + parent: functions +keywords: [] +signature: ["os.Getenv VARIABLE", "getenv VARIABLE"] +relatedfuncs: [] +--- +Examples: + +```go-html-template - {{ os.Getenv "HOME" }} --> /home/victor - {{ os.Getenv "USER" }} --> victor ++{{ os.Getenv "HOME" }} → /home/victor ++{{ os.Getenv "USER" }} → victor +``` + +You can pass values when building your site: + +```bash +MY_VAR1=foo MY_VAR2=bar hugo + +OR + +export MY_VAR1=foo +export MY_VAR2=bar +hugo +``` + +And then retrieve the values within a template: + +```go-html-template - {{ os.Getenv "MY_VAR1" }} --> foo - {{ os.Getenv "MY_VAR2" }} --> bar ++{{ os.Getenv "MY_VAR1" }} → foo ++{{ os.Getenv "MY_VAR2" }} → bar +``` + +With Hugo v0.91.0 and later, you must explicitly allow access to environment variables. For details, review [Hugo's Security Policy](/about/security-model/#security-policy). By default, environment variables beginning with `HUGO_` are allowed when using the `os.Getenv` function. diff --cc docs/content/en/functions/merge.md index 68e561450,000000000..ed370549e mode 100644,000000..100644 --- a/docs/content/en/functions/merge.md +++ b/docs/content/en/functions/merge.md @@@ -1,67 -1,0 +1,67 @@@ +--- +title: merge +description: "Returns the result of merging two or more maps." +categories: [functions] +menu: + docs: + parent: functions +keywords: [dictionary] +signature: ["collections.Merge MAP MAP...", "merge MAP MAP..."] +relatedfuncs: [dict, append, reflect.IsMap, reflect.IsSlice] +--- + +Returns the result of merging two or more maps from left to right. If a key already exists, `merge` updates its value. If a key is absent, `merge` inserts the value under the new key. + +Key handling is case-insensitive. + +The following examples use these map definitions: + +```go-html-template +{{ $m1 := dict "x" "foo" }} +{{ $m2 := dict "x" "bar" "y" "wibble" }} +{{ $m3 := dict "x" "baz" "y" "wobble" "z" (dict "a" "huey") }} +``` + +Example 1 + +```go-html-template +{{ $merged := merge $m1 $m2 $m3 }} + - {{ $merged.x }} --> baz - {{ $merged.y }} --> wobble - {{ $merged.z.a }} --> huey ++{{ $merged.x }} → baz ++{{ $merged.y }} → wobble ++{{ $merged.z.a }} → huey +``` + +Example 2 + +```go-html-template +{{ $merged := merge $m3 $m2 $m1 }} + - {{ $merged.x }} --> foo - {{ $merged.y }} --> wibble - {{ $merged.z.a }} --> huey ++{{ $merged.x }} → foo ++{{ $merged.y }} → wibble ++{{ $merged.z.a }} → huey +``` + +Example 3 + +```go-html-template +{{ $merged := merge $m2 $m3 $m1 }} + - {{ $merged.x }} --> foo - {{ $merged.y }} --> wobble - {{ $merged.z.a }} --> huey ++{{ $merged.x }} → foo ++{{ $merged.y }} → wobble ++{{ $merged.z.a }} → huey +``` + +Example 4 + +```go-html-template +{{ $merged := merge $m1 $m3 $m2 }} + - {{ $merged.x }} --> bar - {{ $merged.y }} --> wibble - {{ $merged.z.a }} --> huey ++{{ $merged.x }} → bar ++{{ $merged.y }} → wibble ++{{ $merged.z.a }} → huey +``` + +{{% note %}} +Regardless of depth, merging only applies to maps. For slices, use [append](/functions/append). +{{% /note %}} diff --cc docs/content/en/functions/os.Stat.md index 9ace3b8bf,000000000..51d35ae2f mode 100644,000000..100644 --- a/docs/content/en/functions/os.Stat.md +++ b/docs/content/en/functions/os.Stat.md @@@ -1,25 -1,0 +1,25 @@@ +--- +title: os.Stat +description: Returns a FileInfo structure describing a file or directory. +categories: [functions] +menu: + docs: + parent: functions +keywords: [files] +signature: ["os.Stat PATH"] +relatedfuncs: ['os.FileExists','os.ReadDir','os.ReadFile'] +--- +The `os.Stat` function attempts to resolve the path relative to the root of your project directory. If a matching file or directory is not found, it will attempt to resolve the path relative to the [`contentDir`](/getting-started/configuration#contentdir). A leading path separator (`/`) is optional. + +```go-html-template +{{ $f := os.Stat "README.md" }} - {{ $f.IsDir }} --> false (bool) - {{ $f.ModTime }} --> 2021-11-25 10:06:49.315429236 -0800 PST (time.Time) - {{ $f.Name }} --> README.md (string) - {{ $f.Size }} --> 241 (int64) ++{{ $f.IsDir }} → false (bool) ++{{ $f.ModTime }} → 2021-11-25 10:06:49.315429236 -0800 PST (time.Time) ++{{ $f.Name }} → README.md (string) ++{{ $f.Size }} → 241 (int64) + +{{ $d := os.Stat "content" }} - {{ $d.IsDir }} --> true (bool) ++{{ $d.IsDir }} → true (bool) +``` + +Details of the `FileInfo` structure are available in the [Go documentation](https://pkg.go.dev/io/fs#FileInfo). diff --cc docs/content/en/functions/readdir.md index 9fc4d3013,000000000..a76e3c5f6 mode 100644,000000..100644 --- a/docs/content/en/functions/readdir.md +++ b/docs/content/en/functions/readdir.md @@@ -1,45 -1,0 +1,45 @@@ +--- +title: readDir +description: Returns an array of FileInfo structures sorted by file name, one element for each directory entry. +categories: [functions] +menu: + docs: + parent: functions +keywords: [files] +signature: ["os.ReadDir PATH", "readDir PATH"] +relatedfuncs: ['os.FileExists','os.ReadFile','os.Stat'] +--- +The `os.ReadDir` function resolves the path relative to the root of your project directory. A leading path separator (`/`) is optional. + +With this directory structure: + +```text +content/ +├── about.md +├── contact.md +└── news/ + ├── article-1.md + └── article-2.md +``` + +This template code: + +```go-html-template +{{ range os.ReadDir "content" }} - {{ .Name }} --> {{ .IsDir }} ++ {{ .Name }} → {{ .IsDir }} +{{ end }} +``` + +Produces: + +```html +about.md --> false +contact.md --> false +news --> true +``` + +Note that `os.ReadDir` is not recursive. + +Details of the `FileInfo` structure are available in the [Go documentation](https://pkg.go.dev/io/fs#FileInfo). + +For more information on using `readDir` and `readFile` in your templates, see [Local File Templates](/templates/files). diff --cc docs/content/en/functions/replacere.md index 22f81a2f5,000000000..8c3cc13c2 mode 100644,000000..100644 --- a/docs/content/en/functions/replacere.md +++ b/docs/content/en/functions/replacere.md @@@ -1,58 -1,0 +1,44 @@@ +--- +title: replaceRE +description: Returns a string, replacing all occurrences of a regular expression with a replacement pattern. +categories: [functions] +menu: + docs: + parent: functions +keywords: [regex] +signature: + - "replaceRE PATTERN REPLACEMENT INPUT [LIMIT]" + - "strings.ReplaceRE PATTERN REPLACEMENT INPUT [LIMIT]" +relatedfuncs: [findRE, FindRESubmatch, replace] +--- +By default, `replaceRE` replaces all matches. You can limit the number of matches with an optional LIMIT parameter. + - When specifying the regular expression, use a raw [string literal] (backticks) instead of an interpreted string literal (double quotes) to simplify the syntax. With an interpreted string literal you must escape backslashes. - - [string literal]: https://go.dev/ref/spec#String_literals - - This function uses the [RE2] regular expression library. See the [RE2 syntax documentation] for details. Note that the RE2 `\C` escape sequence is not supported. - - [RE2]: https://github.com/google/re2/ - [RE2 syntax documentation]: https://github.com/google/re2/wiki/Syntax/ - - {{% note %}} - The RE2 syntax is a subset of that accepted by [PCRE], roughly speaking, and with various [caveats]. - - [caveats]: https://swtch.com/~rsc/regexp/regexp3.html#caveats - [PCRE]: https://www.pcre.org/ - {{% /note %}} ++{{% readfile file="/functions/common/regular-expressions.md" %}} + +This example replaces two or more consecutive hyphens with a single hyphen: + +```go-html-template +{{ $s := "a-b--c---d" }} +{{ replaceRE `(-{2,})` "-" $s }} → a-b-c-d +``` + +To limit the number of replacements to one: + +```go-html-template +{{ $s := "a-b--c---d" }} +{{ replaceRE `(-{2,})` "-" $s 1 }} → a-b-c---d +``` + +You can use `$1`, `$2`, etc. within the replacement string to insert the groups captured within the regular expression: + +```go-html-template +{{ $s := "http://gohugo.io/docs" }} +{{ replaceRE "^https?://([^/]+).*" "$1" $s }} → gohugo.io +``` + +{{% note %}} +You can write and test your regular expression using [regex101.com](https://regex101.com/). Be sure to select the Go flavor before you begin. +{{% /note %}} + +[RE2]: https://github.com/google/re2/wiki/Syntax +[string literal]: https://go.dev/ref/spec#String_literals diff --cc docs/content/en/functions/scratch.md index 2e00f41bd,000000000..16e502b84 mode 100644,000000..100644 --- a/docs/content/en/functions/scratch.md +++ b/docs/content/en/functions/scratch.md @@@ -1,147 -1,0 +1,147 @@@ +--- +title: .Scratch +description: Acts as a "scratchpad" to store and manipulate data. +keywords: [iteration] +categories: [functions] +menu: + docs: + parent: functions +toc: +signature: [] +relatedfuncs: [] +aliases: [/extras/scratch/,/doc/scratch/] +--- + +Scratch is a Hugo feature designed to conveniently manipulate data in a Go Template world. It is either a Page or Shortcode method for which the resulting data will be attached to the given context, or it can live as a unique instance stored in a variable. + +{{% note %}} +Note that Scratch was initially created as a workaround for a [Go template scoping limitation](https://github.com/golang/go/issues/10608) that affected Hugo versions prior to 0.48. For a detailed analysis of `.Scratch` and contextual use cases, see [this blog post](https://regisphilibert.com/blog/2017/04/hugo-scratch-explained-variable/). +{{% /note %}} + +### Contexted `.Scratch` vs. local `newScratch` + +Since Hugo 0.43, there are two different ways of using Scratch: + +#### The Page's `.Scratch` + +`.Scratch` is available as a Page method or a Shortcode method and attaches the "scratched" data to the given page. Either a Page or a Shortcode context is required to use `.Scratch`. + +```go-html-template +{{ .Scratch.Set "greeting" "bonjour" }} +{{ range .Pages }} + {{ .Scratch.Set "greeting" (print "bonjour" .Title) }} +{{ end }} +``` + +#### The local `newScratch` + +A Scratch instance can also be assigned to any variable using the `newScratch` function. In this case, no Page or Shortcode context is required and the scope of the scratch is only local. The methods detailed below are available from the variable the Scratch instance was assigned to. + +```go-html-template +{{ $data := newScratch }} +{{ $data.Set "greeting" "hola" }} +``` + +### Methods + +A Scratch has the following methods: + +{{% note %}} +Note that the following examples assume a [local Scratch instance](#the-local-newscratch) has been stored in `$scratch`. +{{% /note %}} + +#### .Set + +Set the value of a given key. + +```go-html-template +{{ $scratch.Set "greeting" "Hello" }} +``` + +#### .Get + +Get the value of a given key. + +```go-html-template +{{ $scratch.Set "greeting" "Hello" }} +---- +{{ $scratch.Get "greeting" }} > Hello +``` + +#### .Add + +Add a given value to existing value(s) of the given key. + - For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list. ++For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be [appended](/functions/append/) to that list. + +```go-html-template +{{ $scratch.Add "greetings" "Hello" }} +{{ $scratch.Add "greetings" "Welcome" }} +---- +{{ $scratch.Get "greetings" }} > HelloWelcome +``` + +```go-html-template +{{ $scratch.Add "total" 3 }} +{{ $scratch.Add "total" 7 }} +---- +{{ $scratch.Get "total" }} > 10 +``` + +```go-html-template +{{ $scratch.Add "greetings" (slice "Hello") }} +{{ $scratch.Add "greetings" (slice "Welcome" "Cheers") }} +---- +{{ $scratch.Get "greetings" }} > []interface {}{"Hello", "Welcome", "Cheers"} +``` + +#### .SetInMap + +Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`. + +```go-html-template +{{ $scratch.SetInMap "greetings" "english" "Hello" }} +{{ $scratch.SetInMap "greetings" "french" "Bonjour" }} +---- +{{ $scratch.Get "greetings" }} > map[french:Bonjour english:Hello] +``` + +#### .DeleteInMap +Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`. + +```go-html-template +{{ .Scratch.SetInMap "greetings" "english" "Hello" }} +{{ .Scratch.SetInMap "greetings" "french" "Bonjour" }} +---- +{{ .Scratch.DeleteInMap "greetings" "english" }} +---- +{{ .Scratch.Get "greetings" }} > map[french:Bonjour] +``` + +#### .GetSortedMapValues + +Return an array of values from `key` sorted by `mapKey`. + +```go-html-template +{{ $scratch.SetInMap "greetings" "english" "Hello" }} +{{ $scratch.SetInMap "greetings" "french" "Bonjour" }} +---- +{{ $scratch.GetSortedMapValues "greetings" }} > [Hello Bonjour] +``` + +#### .Delete + +Remove the given key. + +```go-html-template +{{ $scratch.Set "greeting" "Hello" }} +---- +{{ $scratch.Delete "greeting" }} +``` + +#### .Values + +Return the raw backing map. Note that you should only use this method on the locally scoped Scratch instances you obtain via [`newScratch`](#the-local-newscratch), not `.Page.Scratch` etc., as that will lead to concurrency issues. + + +[pagevars]: /variables/page/ diff --cc docs/content/en/functions/strings.ContainsNonSpace.md index 000000000,000000000..eafe292f5 new file mode 100644 --- /dev/null +++ b/docs/content/en/functions/strings.ContainsNonSpace.md @@@ -1,0 -1,0 +1,27 @@@ ++--- ++title: strings.ContainsNonSpace ++description: Reports whether a string contains any non-space characters as defined by Unicode’s White Space property. ++categories: [functions] ++menu: ++ docs: ++ parent: functions ++keywords: [whitespace space] ++signature: ["strings.ContainsNonSpace STRING"] ++relatedfuncs: ["strings.Contains","strings.ContainsAny"] ++--- ++ ++```go-html-template ++{{ strings.ContainsNonSpace "\n" }} → false ++{{ strings.ContainsNonSpace " " }} → false ++{{ strings.ContainsNonSpace "\n abc" }} → true ++``` ++ ++Common white space characters include: ++ ++```text ++'\t', '\n', '\v', '\f', '\r', ' ' ++``` ++ ++See the [Unicode Character Database] for a complete list. ++ ++[Unicode Character Database]: https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt diff --cc docs/content/en/functions/transform.Unmarshal.md index ca5433761,000000000..7d0920da8 mode 100644,000000..100644 --- a/docs/content/en/functions/transform.Unmarshal.md +++ b/docs/content/en/functions/transform.Unmarshal.md @@@ -1,73 -1,0 +1,73 @@@ +--- +title: transform.Unmarshal +description: "`transform.Unmarshal` (alias `unmarshal`) parses the input and converts it into a map or an array. Supported formats are JSON, TOML, YAML, XML and CSV." +categories: [functions] +menu: + docs: + parent: functions +keywords: [] +signature: ["RESOURCE or STRING | transform.Unmarshal [OPTIONS]"] +--- + +The function accepts either a `Resource` created in [Hugo Pipes](/hugo-pipes/) or via [Page Bundles](/content-management/page-bundles/), or simply a string. The two examples below will produce the same map: + +```go-html-template +{{ $greetings := "hello = \"Hello Hugo\"" | transform.Unmarshal }}` +``` + +```go-html-template +{{ $greetings := "hello = \"Hello Hugo\"" | resources.FromString "data/greetings.toml" | transform.Unmarshal }} +``` + +In both the above examples, you get a map you can work with: + +```go-html-template +{{ $greetings.hello }} +``` + +The above prints `Hello Hugo`. + +## CSV options + +Unmarshal with CSV as input has some options you can set: + +delimiter +: The delimiter used, default is `,`. + +comment +: The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.: + +Example: + +```go-html-template +{{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }} +``` + +## XML data + +As a convenience, Hugo allows you to access XML data in the same way that you access JSON, TOML, and YAML: you do not need to specify the root node when accessing the data. + +To get the contents of `` in the document below, you use `{{ .message.title }}`: + +```xml +<root> + <message> + <title>Hugo rocks! + Thanks for using Hugo + + +``` + +The following example lists the items of an RSS feed: + +```go-html-template +{{ with resources.GetRemote "https://example.com/rss.xml" | transform.Unmarshal }} - {{ range .channel.item }} - {{ .title | plainify | htmlUnescape }}
-

{{ .description | plainify | htmlUnescape }}

- {{ $link := .link | plainify | htmlUnescape }} - {{ $link }}
-
- {{ end }} ++ {{ range .channel.item }} ++ {{ .title | plainify | htmlUnescape }}
++

{{ .description | plainify | htmlUnescape }}

++ {{ $link := .link | plainify | htmlUnescape }} ++ {{ $link }}
++
++ {{ end }} +{{ end }} +``` diff --cc docs/content/en/functions/uniq.md index 4584ec5ad,000000000..aecdccf95 mode 100644,000000..100644 --- a/docs/content/en/functions/uniq.md +++ b/docs/content/en/functions/uniq.md @@@ -1,15 -1,0 +1,15 @@@ +--- +title: uniq +description: Takes in a slice or array and returns a slice with duplicate elements removed. +categories: [functions] +menu: + docs: + parent: functions +keywords: [multilingual,i18n,urls] +signature: [uniq SET] +--- + + +```go-html-template - {{ slice 1 3 2 1 | uniq }} --> [1 3 2] ++{{ slice 1 3 2 1 | uniq }} → [1 3 2] +``` diff --cc docs/content/en/functions/urlize.md index 8c9aeb1c3,000000000..7a9cf25e8 mode 100644,000000..100644 --- a/docs/content/en/functions/urlize.md +++ b/docs/content/en/functions/urlize.md @@@ -1,62 -1,0 +1,62 @@@ +--- +title: urlize +description: Takes a string, sanitizes it for usage in URLs, and converts spaces to hyphens. +categories: [functions] +menu: + docs: + parent: functions +keywords: [urls,strings] +signature: ["urlize INPUT"] +relatedfuncs: [] +--- + +The following examples pull from a content file with the following front matter: + +{{< code-toggle file="content/blog/greatest-city.md" fm=true copy=false >}} +title = "The World's Greatest City" +location = "Chicago IL" +tags = ["pizza","beer","hot dogs"] +{{< /code-toggle >}} + +The following might be used as a partial within a [single page template][singletemplate]: + +{{< code file="layouts/partials/content-header.html" >}} +
-

{{ .Title }}

- {{ with .Params.location }} - - {{ end }} - - {{ with .Params.tags }} ++

{{ .Title }}

++ {{ with .Params.location }} ++ ++ {{ end }} ++ ++ {{ with .Params.tags }} +
    - {{ range .}} -
  • - {{ . }} -
  • - {{ end }} ++ {{ range .}} ++
  • ++ {{ . }} ++
  • ++ {{ end }} +
- {{ end }} ++ {{ end }} +
+{{< /code >}} + +The preceding partial would then output to the rendered page as follows: + +```html +
+

The World's Greatest City

+ + +
+``` + +[singletemplate]: /templates/single-page-templates/ diff --cc docs/content/en/functions/where.md index f2e264235,000000000..9618ea4c6 mode 100644,000000..100644 --- a/docs/content/en/functions/where.md +++ b/docs/content/en/functions/where.md @@@ -1,193 -1,0 +1,180 @@@ +--- +title: where +description: Filters an array to only the elements containing a matching value for a given field. +categories: [functions] +menu: + docs: + parent: functions +keywords: [filtering] +signature: ["where COLLECTION KEY [OPERATOR] MATCH"] +relatedfuncs: [intersect,first,after,last] +toc: true +--- + +`where` filters an array to only the elements containing a matching +value for a given field. + +It works in a similar manner to the [`where` keyword in +SQL][wherekeyword]. + +```go-html-template +{{ range where .Pages "Section" "foo" }} + {{ .Content }} +{{ end }} +``` + +It can be used by dot-chaining the second argument to refer to a nested element of a value. + +{{< code-toggle file="content/example.md" fm=true copy=false >}} +title: Example +series: golang +{{< /code-toggle >}} + +```go-html-template +{{ range where .Site.Pages "Params.series" "golang" }} + {{ .Content }} +{{ end }} +``` + +It can also be used with the logical operators `!=`, `>=`, `in`, etc. Without an operator, `where` compares a given field with a matching value equivalent to `=`. + +```go-html-template +{{ range where .Pages "Section" "!=" "foo" }} + {{ .Content }} +{{ end }} +``` + +The following logical operators are available with `where`: + +`=`, `==`, `eq` +: `true` if a given field value equals a matching value + +`!=`, `<>`, `ne` +: `true` if a given field value doesn't equal a matching value + +`>=`, `ge` +: `true` if a given field value is greater than or equal to a matching value + +`>`, `gt` +: `true` if a given field value is greater than a matching value + +`<=`, `le` +: `true` if a given field value is lesser than or equal to a matching value + +`<`, `lt` +: `true` if a given field value is lesser than a matching value + +`in` +: `true` if a given field value is included in a matching value; a matching value must be an array or a slice + +`not in` +: `true` if a given field value isn't included in a matching value; a matching value must be an array or a slice + +`intersect` +: `true` if a given field value that is a slice/array of strings or integers contains elements in common with the matching value; it follows the same rules as the [`intersect` function][intersect]. + +`like` +: `true` if a given field value matches a regular expression. Use the `like` operator to compare `string` values. Returns `false` when comparing other data types to the regular expression. + +## Use `where` with boolean values +When using booleans you should not put quotation marks. +```go-html-template +{{ range where .Pages "Draft" true }} +

{{ .Title }}

+{{ end }} +``` + +## Use `where` with `intersect` + +```go-html-template +{{ range where .Site.Pages "Params.tags" "intersect" .Params.tags }} + {{ if ne .Permalink $.Permalink }} + {{ .Render "summary" }} + {{ end }} +{{ end }} +``` + +You can also put the returned value of the `where` clauses into a variable: + +{{< code file="where-intersect-variables.html" >}} +{{ $v1 := where .Site.Pages "Params.a" "v1" }} +{{ $v2 := where .Site.Pages "Params.b" "v2" }} +{{ $filtered := $v1 | intersect $v2 }} +{{ range $filtered }} +{{ end }} +{{< /code >}} + +## Use `where` with `like` + +This example matches pages where the "foo" parameter begins with "ab": + +```go-html-template - {{ range where site.RegularPages "Params.foo" "like" "^ab" }} ++{{ range where site.RegularPages "Params.foo" "like" `^ab` }} +

{{ .LinkTitle }}

+{{ end }} +``` + - When specifying the regular expression, use a raw [string literal] (backticks) instead of an interpreted string literal (double quotes) to simplify the syntax. With an interpreted string literal you must escape backslashes. - - [string literal]: https://go.dev/ref/spec#String_literals - - Go's regular expression package implements the [RE2 syntax]. Note that the RE2 `\C` escape sequence is not supported. - - [RE2 syntax]: https://github.com/google/re2/wiki/Syntax/ - - {{% note %}} - The RE2 syntax is a subset of that accepted by [PCRE], roughly speaking, and with various [caveats]. - - [caveats]: https://swtch.com/~rsc/regexp/regexp3.html#caveats - [PCRE]: https://www.pcre.org/ - {{% /note %}} ++{{% readfile file="/functions/common/regular-expressions.md" %}} + +## Use `where` with `first` + +Using `first` and `where` together can be very +powerful. Below snippet gets a list of posts only from [**main +sections**](#mainsections), sorts it using the [default +ordering](/templates/lists/) for lists (i.e., `weight => date`), and +then ranges through only the first 5 posts in that list: + +{{< code file="first-and-where-together.html" >}} +{{ range first 5 (where site.RegularPages "Type" "in" site.Params.mainSections) }} + {{ .Content }} +{{ end }} +{{< /code >}} + +## Nest `where` clauses + +You can also nest `where` clauses to drill down on lists of content by more than one parameter. The following first grabs all pages in the "blog" section and then ranges through the result of the first `where` clause and finds all pages that are *not* featured: + +```go-html-template +{{ range where (where .Pages "Section" "blog" ) "Params.featured" "!=" true }} +``` + +## Unset fields + +Filtering only works for set fields. To check whether a field is set or exists, you can use the operand `nil`. + +This can be useful to filter a small amount of pages from a large pool. Instead of setting a field on all pages, you can set that field on required pages only. + +Only the following operators are available for `nil` + +* `=`, `==`, `eq`: True if the given field is not set. +* `!=`, `<>`, `ne`: True if the given field is set. + +```go-html-template +{{ range where .Pages "Params.specialpost" "!=" nil }} + {{ .Content }} +{{ end }} +``` + +## Portable `where` filters -- `site.Params.mainSections` {#mainsections} + +**This is especially important for themes.** + +To list the most relevant pages on the front page or similar, you +should use the `site.Params.mainSections` list instead of comparing +section names to hard-coded values like `"posts"` or `"post"`. + +```go-html-template +{{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }} +``` + +If the user has not set this configuration parameter in their site configuration, it will default to the *section with the most pages*. + +The user can override the default: + +{{< code-toggle file="hugo" >}} +[params] + mainSections = ["blog", "docs"] +{{< /code-toggle >}} + +[intersect]: /functions/intersect/ +[wherekeyword]: https://www.techonthenet.com/sql/where.php diff --cc docs/content/en/getting-started/configuration.md index 21f4eb67f,000000000..ea82f1b53 mode 100644,000000..100644 --- a/docs/content/en/getting-started/configuration.md +++ b/docs/content/en/getting-started/configuration.md @@@ -1,870 -1,0 +1,870 @@@ +--- +title: Configure Hugo +linkTitle: Configuration +description: How to configure your Hugo site. +categories: [fundamentals,getting started] +keywords: [configuration,toml,yaml,json] +menu: + docs: + parent: getting-started + weight: 40 +weight: 40 +aliases: [/overview/source-directory/,/overview/configuration/] +toc: true +--- + +## Configuration file + +Hugo uses the `hugo.toml`, `hugo.yaml`, or `hugo.json` (if found in the +site root) as the default site configuration file. + +The user can choose to override that default with one or more site configuration files using the command-line `--config` switch. + +Examples: + +```txt +hugo --config debugconfig.toml +hugo --config a.toml,b.toml,c.toml +``` + +{{% note %}} +Multiple site configuration files can be specified as a comma-separated string to the `--config` switch. +{{% /note %}} + +## hugo.toml vs config.toml + +In Hugo 0.110.0 we changed the default configuration base file name to `hugo`, e.g. `hugo.toml`. We will still look for `config.toml` etc., but we recommend you eventually rename it (but you need to wait if you want to support older Hugo versions). The main reason we're doing this is to make it easier for code editors and build tools to identify this as a Hugo configuration file and project. + +{{< new-in "0.110.0" >}} + +## Configuration directory + +In addition to using a single site configuration file, one can use the `configDir` directory (default to `config/`) to maintain easier organization and environment specific settings. + +- Each file represents a configuration root object, such as `params.toml` for `[Params]`, `menu(s).toml` for `[Menu]`, `languages.toml` for `[Languages]` etc... +- Each file's content must be top-level, for example: + +{{< code-toggle file="hugo" >}} +[Params] + foo = "bar" +{{< /code-toggle >}} + +{{< code-toggle file="params" >}} +foo = "bar" +{{< /code-toggle >}} + +- Each directory holds a group of files containing settings unique to an environment. +- Files can be localized to become language specific. + +```txt +├── config +│ ├── _default +│ │ ├── hugo.toml +│ │ ├── languages.toml +│ │ ├── menus.en.toml +│ │ ├── menus.zh.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 `googleAnalytics = "G-XXXXXXXX"` in `hugo.toml`. Now consider the following scenario: +- You don't want the Analytics code to be loaded in development i.e. in your `localhost` +- You want to use separate googleAnalytics IDs for your production & staging environments (say): + - `G-PPPPPPPP` for production + - `G-SSSSSSSS` for staging + +This is how you need to configure your `hugo.toml` files considering the above scenario: +1. In `_default/hugo.toml` you don't need to mention `googleAnalytics` parameter at all. This ensures that no Google Analytics code is loaded in your development server i.e. when you run `hugo server`. This works since, by default Hugo sets `Environment=development` when you run `hugo server` which uses the configuration files from `_default` folder +2. In `production/hugo.toml` you just need to have one line: + + ```googleAnalytics = "G-PPPPPPPP"``` + + You don't need to mention all other parameters like `title`, `baseURL`, `theme` etc. again in this configuration file. You need to mention only those parameters which are different or new for the production environment. This is due to the fact that Hugo is going to __merge__ this on top of `_default/hugo.toml`. Now when you run `hugo` (build command), by default hugo sets `Environment=production`, so the `G-PPPPPPPP` analytics code will be there in your production website +3. Similarly in `staging/hugo.toml` you just need to have one line: + + ```googleAnalytics = "G-SSSSSSSS"``` + + Now you need to tell Hugo that you are using the staging environment. So your build command should be `hugo --environment staging` which will load the `G-SSSSSSSS` analytics code in your staging website + +{{% note %}} +Default environments are __development__ with `hugo server` and __production__ with `hugo`. +{{%/ note %}} + +## 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 config="mergeStrategy" skipHeader=true />}} + +## All configuration settings + +The following is the full list of Hugo-defined variables. Users may choose to override those values in their site configuration file(s). + +### archetypeDir + +**Default value:** "archetypes" + +The directory where Hugo finds archetype files (content templates). {{% module-mounts-note %}} + +### assetDir + +**Default value:** "assets" + +The directory where Hugo finds asset files used in [Hugo Pipes](/hugo-pipes/). {{% module-mounts-note %}} + +### baseURL + +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 (false) + +**Default value:** false + +Include drafts when building. + +### buildExpired + +**Default value:** false + +Include content already expired. + +### buildFuture + +**Default value:** false + +Include content with publishdate in the future. + +### caches + +See [Configure File Caches](#configure-file-caches) + +### cascade + +Pass down default configuration values (front matter) to pages in the content tree. The options in site configuration is the same as in page front matter, see [Front Matter Cascade](/content-management/front-matter#front-matter-cascade). + +### canonifyURLs + +**Default value:** false + - Enable to turn relative URLs into absolute. ++Enable to turn relative URLs into absolute. See [details](/content-management/urls/#canonical-urls). + +### cleanDestinationDir + +**Default value:** false + +When building, removes files from destination not found in static directories. + +### contentDir + +**Default value:** "content" + +The directory from where Hugo reads content files. {{% module-mounts-note %}} + +### copyright + +**Default value:** "" + +Copyright notice for your site, typically displayed in the footer. + +### dataDir + +**Default value:** "data" + +The directory from where Hugo reads data files. {{% module-mounts-note %}} + +### defaultContentLanguage + +**Default value:** "en" + +Content without language indicator will default to this language. + +### defaultContentLanguageInSubdir + +**Default value:** false + +Render the default content language in subdir, e.g. `content/en/`. The site root `/` will then redirect to `/en/`. + +### disableAliases + +**Default value:** false + +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. + +### disableHugoGeneratorInject + +**Default value:** false + +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. + +### disableKinds + +**Default value:** [] + +Enable disabling of all pages of the specified *Kinds*. Allowed values in this list: `"page"`, `"home"`, `"section"`, `"taxonomy"`, `"term"`, `"RSS"`, `"sitemap"`, `"robotsTXT"`, `"404"`. + +### disableLiveReload + +**Default value:** false + +Disable automatic live reloading of browser window. + +### disablePathToLower + +**Default value:** false + +Do not convert the url/path to lowercase. + +### enableEmoji + +**Default value:** false + +Enable Emoji emoticons support for page content; see the [Emoji Cheat Sheet](https://www.webpagefx.com/tools/emoji-cheat-sheet/). + +### enableGitInfo + +**Default value:** false + +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. + +### enableInlineShortcodes + +**Default value:** false + +Enable inline shortcode support. See [Inline Shortcodes](/templates/shortcode-templates/#inline-shortcodes). + +### enableMissingTranslationPlaceholders + +**Default value:** false + +Show a placeholder instead of the default value or an empty string if a translation is missing. + +### enableRobotsTXT + +**Default value:** false + +Enable generation of `robots.txt` file. + +### frontmatter + +See [Front matter Configuration](#configure-front-matter). + +### googleAnalytics + +**Default value:** "" + +Google Analytics tracking ID. + +### hasCJKLanguage + +**Default value:** false + +If true, auto-detect Chinese/Japanese/Korean Languages in the content. This will make `.Summary` and `.WordCount` behave correctly for CJK languages. + +### imaging + +See [image processing configuration](/content-management/image-processing/#imaging-configuration). + +### languageCode + +**Default value:** "" + +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 internal [RSS template](https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/_default/rss.xml) +- The `lang` attribute of the `` element in the internal [alias template](https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates/alias.html) + +### 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 + +**Default value:** "" + +The editor to use when creating new content. + +### noChmod + +**Default value:** false + +Don't sync permission mode of files. + +### noTimes + +**Default value:** false + +Don't sync modification time of files. + +### outputFormats + +See [Configure Output Formats](#configure-additional-output-formats). + +### paginate + +**Default value:** 10 + +Default number of elements per page in [pagination](/templates/pagination/). + +### paginatePath + +**Default value:** "page" + +The path element used during pagination (`https://example.com/page/2`). + +### permalinks + +See [Content Management](/content-management/urls/#permalinks). + +### pluralizeListTitles + +**Default value:** true + +Pluralize titles in lists. + +### publishDir + +**Default value:** "public" + +The directory to where Hugo will write the final static site (the HTML files etc.). + +### related + +See [Related Content](/content-management/related/#configure-related-content). + +### relativeURLs + +**Default value:** false + - Enable this to make all relative URLs relative to content root. Note that this does not affect absolute URLs. ++Enable this to make all relative URLs relative to content root. Note that this does not affect absolute URLs. See [details](/content-management/urls/#relative-urls). + +### refLinksErrorLevel + +**Default value:** "ERROR" + +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`). + +### refLinksNotFoundURL + +URL to be used as a placeholder when a page reference cannot be found in `ref` or `relref`. Is used as-is. + +### removePathAccents + +**Default value:** false + +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. + +```text +content/post/hügó.md --> https://example.org/post/hugo/ +``` + +### rssLimit + +**Default value:** -1 (unlimited) + +Maximum number of items in the RSS feed. + +### sectionPagesMenu + +See [Menus](/content-management/menus/#define-in-site-configuration). + +### security + +See [Security Policy](/about/security-model/#security-policy) + +### sitemap + +Default [sitemap configuration](/templates/sitemap-template/#configuration). + +### summaryLength + +**Default value:** 70 + +The length of text in words to show in a [`.Summary`](/content-management/summaries/#automatic-summary-splitting). + +### 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 + +**Default value:** "themes" + +The directory where Hugo reads the themes from. + +### timeout + +**Default value:** "30s" + +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). + +### timeZone + +The time zone (or location), e.g. `Europe/Oslo`, used to parse front matter dates without such information and in the [`time` function](/functions/time/). 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 + +Site title. + +### titleCaseStyle + +**Default value:** "ap" + +See [Configure Title Case](#configure-title-case) + +### uglyURLs + +**Default value:** false + +When enabled, creates URL of the form `/filename.html` instead of `/filename/`. + +### watch + +**Default value:** false + +Watch filesystem for changes and recreate as needed. + +{{% 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 build + +The `build` configuration section contains global build-related configuration options. + +{{< code-toggle file="hugo" >}} +[build] + noJSConfigInAssets = false + useResourceCacheWhen = 'fallback' + [build.buildStats] + disableClasses = false + disableIDs = false + disableTags = false + enable = false +[[build.cachebusters]] + source = 'assets/.*\.(js|ts|jsx|tsx)' + target = '(js|scripts|javascript)' +[[build.cachebusters]] + source = 'assets/.*\.(css|sass|scss)$' + target = '(css|styles|scss|sass)' +[[build.cachebusters]] + source = '(postcss|tailwind)\.config\.js' + target = '(css|styles|scss|sass)' +[[build.cachebusters]] + source = 'assets/.*\.(.*)$' + target = '$1' +{{< /code-toggle >}} + +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]: http://localhost:1313/hugo-pipes/postprocess/#css-purging-with-postcss ++[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 >}} + +Some key points in the above are `writeStats = true`, which 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" copy=false >}} +[[redirects]] +from = "/**" +to = "/404.html" +status = 404 +{{< /code-toggle >}} + +## Configure title case + +Set `titleCaseStyle` to specify the title style used by the [title](/functions/title/) template function and the automatic section titles in Hugo. + +Can be one of: + +* `ap` (default), the capitalization rules in the [Associated Press (AP) Stylebook] +* `chicago`, the [Chicago Manual of Style] +* `go`, Go's convention of capitalizing every word. +* `firstupper`, capitalize the first letter of the first word. +* `none`, no capitalization. + +[Associated Press (AP) 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 + +HUGO_NUMWORKERMULTIPLIER +: Can be set to increase or reduce the number of workers used in parallel processing in Hugo. If not set, the number of logical CPUs will be used. + +## Configuration lookup order + +Similar to the template [lookup order], Hugo has a default set of rules for searching for a configuration file in the root of your website's source directory as a default behavior: + +1. `./hugo.toml` +2. `./hugo.yaml` +3. `./hugo.json` + +In your configuration file, you can direct Hugo as to how you want your website rendered, control your website's menus, and arbitrarily define site-wide parameters specific to your project. + +## Example configuration + +The following is a typical example of a configuration file. The values nested under `params:` will populate the [`.Site.Params`] variable for use in [templates]: + +{{< code-toggle file="hugo" >}} +baseURL: "https://yoursite.example.com/" +title: "My Hugo Site" +permalinks: + posts: /:year/:month/:title/ +params: + Subtitle: "Hugo is Absurdly Fast!" + AuthorName: "Jon Doe" + GitHubUser: "spf13" + ListOfFoo: + - "foo1" + - "foo2" + SidebarRecentLimit: 5 +{{< /code-toggle >}} + +## 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. + +{{< todo >}} +Test and document setting parameters via JSON env var. +{{< /todo >}} + +## 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. + +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 copy=false file="hugo" >}} +ignoreFiles = ['\.foo$', '\.boo$'] +{{< /code-toggle >}} + +To ignore a file using the absolute file path: + +{{< code-toggle copy=false 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 file="hugo" >}} +[frontmatter] +date = ["date", "publishDate", "lastmod"] +lastmod = [":git", "lastmod", "date", "publishDate"] +publishDate = ["publishDate", "date"] +expiryDate = ["expiryDate"] +{{< /code-toggle >}} + +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 additional output formats + +Hugo v0.20 introduced the ability to render your content to multiple output formats (e.g., to JSON, AMP html, or CSV). See [Output Formats] for information on how to add these values to your Hugo project's configuration file. + +## Configure 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 file="hugo" >}} +[caches] +[caches.getjson] +dir = ":cacheDir/:project" +maxAge = -1 +[caches.getcsv] +dir = ":cacheDir/:project" +maxAge = -1 +[caches.getresource] +dir = ":cacheDir/:project" +maxAge = -1 +[caches.images] +dir = ":resourceDir/_gen" +maxAge = -1 +[caches.assets] +dir = ":resourceDir/_gen" +maxAge = -1 +[caches.modules] +dir = ":cacheDir/modules" +maxAge = -1 +{{< /code-toggle >}} + +You can override any of these cache settings in your own `hugo.toml`. + +### The keywords explained + +`:cacheDir` +: See [Configure cacheDir](#configure-cachedir). + +`:project` +: 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` +: This is the value of the `resourceDir` configuration option. + +maxAge +: 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 +: The absolute path to where the files for this cache will be stored. Allowed starting placeholders are `:cacheDir` and `:resourceDir` (see above). + +## Configuration format specs + +- [TOML Spec][toml] +- [YAML Spec][yaml] +- [JSON Spec][json] + +[`.Site.Params`]: /variables/site/ +[directory structure]: /getting-started/directory-structure +[json]: https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf "Specification for JSON, JavaScript Object Notation" +[lookup order]: /templates/lookup-order/ +[Output Formats]: /templates/output-formats/ +[templates]: /templates/ +[toml]: https://github.com/toml-lang/toml +[yaml]: https://yaml.org/spec/ +[static-files]: /content-management/static-files/ + + +# 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 env 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_CONFIG_HOME` as specified by [basedir-spec-latest](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) if non-empty, else `$HOME/.config`. On MacOS, this is `$HOME/Library/Application Support`. On Windows, this is`%AppData%`. On Plan 9, this is `$home/lib`. {{< new-in "0.116.0" >}} ++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`. ++If you want to know the current value of `cacheDir`, you can run `hugo config`, e.g: `hugo config | grep cachedir`. diff --cc docs/content/en/hosting-and-deployment/hosting-on-github/index.md index 47a7074b7,000000000..dd8bf5583 mode 100644,000000..100644 --- a/docs/content/en/hosting-and-deployment/hosting-on-github/index.md +++ b/docs/content/en/hosting-and-deployment/hosting-on-github/index.md @@@ -1,178 -1,0 +1,178 @@@ +--- +title: Host on GitHub Pages +description: Deploy Hugo as a GitHub Pages project or personal/organizational site and automate the whole process with Github Actions +categories: [hosting and deployment] +keywords: [github,git,deployment,hosting] +menu: + docs: + parent: hosting-and-deployment +toc: true +aliases: [/tutorials/github-pages-blog/] +--- + +GitHub provides free and fast static hosting over SSL for personal, organization, or project pages directly from a GitHub repository via its GitHub Pages service and automating development workflows and build with GitHub Actions. + +## Prerequisites + +1. [Create a GitHub account] +2. [Install Git] +3. [Create a Hugo site] and test it locally with `hugo server`. + +[Create a GitHub account]: https://github.com/signup +[Install Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git +[Create a Hugo site]: /getting-started/quick-start/ + +## Types of sites + +There are three types of GitHub Pages sites: project, user, and organization. Project sites are connected to a specific project hosted on GitHub. User and organization sites are connected to a specific account on GitHub.com. + +{{% note %}} +See the [GitHub Pages documentation] to understand the requirements for repository ownership and naming. + +[GitHub Pages documentation]: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites +{{% /note %}} + + +[GitHub Pages documentation]: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites + +## Procedure + +Step 1 +: Create a GitHub repository. + +Step 2 +: Push your local repository to GitHub. + +Step 3 +: Visit your GitHub repository. From the main menu choose **Settings** > **Pages**. In then center of your screen you will see this: + +![screen capture](gh-pages-1.png) +{style="max-width: 280px"} + +Step 4 +: Change the **Source** to `GitHub Actions`. The change is immediate; you do not have to press a Save button. + +![screen capture](gh-pages-2.png) +{style="max-width: 280px"} + +Step 5 +: Create an empty file in your local repository. + +```text +.github/workflows/hugo.yaml +``` + +Step 6 +: Copy and paste the YAML below into the file you created. Change the branch name and Hugo version as needed. + +{{< code file=".github/workflows/hugo.yaml" >}} +# Sample workflow for building and deploying a Hugo site to GitHub Pages +name: Deploy Hugo site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: + - main + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +# Default to bash +defaults: + run: + shell: bash + +jobs: + # Build job + build: + runs-on: ubuntu-latest + env: - HUGO_VERSION: 0.115.1 ++ HUGO_VERSION: 0.115.4 + steps: + - name: Install Hugo CLI + run: | + wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ + && sudo dpkg -i ${{ runner.temp }}/hugo.deb + - name: Install Dart Sass + run: sudo snap install dart-sass + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - name: Setup Pages + id: pages + uses: actions/configure-pages@v3 + - name: Install Node.js dependencies + run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" + - name: Build with Hugo + env: + # For maximum backward compatibility with Hugo modules + HUGO_ENVIRONMENT: production + HUGO_ENV: production + run: | + hugo \ + --gc \ + --minify \ + --baseURL "${{ steps.pages.outputs.base_url }}/" + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: ./public + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 +{{< /code >}} + +Step 7 +: Commit the change to your local repository with a commit message of something like "Add workflow", and push to GitHub. + +Step 8 +: From GitHub's main menu, choose **Actions**. You will see something like this: + +![screen capture](gh-pages-3.png) +{style="max-width: 350px"} + +Step 9 +: When GitHub has finished building and deploying your site, the color of the status indicator will change to green. + +![screen capture](gh-pages-4.png) +{style="max-width: 350px"} + +Step 10 +: Click on the commit message as shown above. You will see this: + +![screen capture](gh-pages-5.png) +{style="max-width: 611px"} + +Under the deploy step, you will see a link to your live site. + +In the future, whenever you push a change from your local repository, GitHub will rebuild your site and deploy the changes. + +## Additional resources + +- [Learn more about GitHub Actions](https://docs.github.com/en/actions) +- [Caching dependencies to speed up workflows](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows) +- [Manage a custom domain for your GitHub Pages site](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages) diff --cc docs/content/en/hosting-and-deployment/hosting-on-gitlab.md index b48a392b7,000000000..964e656ed mode 100644,000000..100644 --- a/docs/content/en/hosting-and-deployment/hosting-on-gitlab.md +++ b/docs/content/en/hosting-and-deployment/hosting-on-gitlab.md @@@ -1,100 -1,0 +1,101 @@@ +--- +title: Host on GitLab Pages +description: GitLab makes it easy to build, deploy, and host your Hugo website via their free GitLab Pages service, which provides native support for Hugo. +categories: [hosting and deployment] +keywords: [hosting,deployment,git,gitlab] +menu: + docs: + parent: hosting-and-deployment +toc: true +aliases: [/tutorials/hosting-on-gitlab/] +--- + +## Assumptions + +* Working familiarity with Git for version control +* Completion of the Hugo [Quick Start] +* A [GitLab account](https://gitlab.com/users/sign_in) +* A Hugo website on your local machine that you are ready to publish + +## BaseURL + +The `baseURL` in your [site configuration](/getting-started/configuration/) must reflect the full URL of your GitLab pages repository if you are using the default GitLab Pages URL (e.g., `https://.gitlab.io//`) and not a custom domain. + +## Configure GitLab CI/CD + +Define your [CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) jobs by creating a `.gitlab-ci.yml` file in the root of your project. + +{{< code file=".gitlab-ci.yml" >}} +variables: - DART_SASS_VERSION: 1.63.6 - HUGO_VERSION: 0.115.3 ++ DART_SASS_VERSION: 1.64.1 ++ HUGO_VERSION: 0.115.4 + NODE_VERSION: 20.x + GIT_DEPTH: 0 + GIT_STRATEGY: clone + GIT_SUBMODULE_STRATEGY: recursive + TZ: America/Los_Angeles + +image: + name: golang:1.20.6-bookworm + +pages: + script: + # Install brotli + - apt-get update + - apt-get install -y brotli + # Install Dart Sass + - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz + - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz - - cp -r dart-sass/* /usr/local/bin ++ - cp -r dart-sass/ /usr/local/bin + - rm -rf dart-sass* ++ - export PATH=/usr/local/bin/dart-sass:$PATH + # Install Hugo + - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb + - apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb + - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb + # Install Node.js + - curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash - + - apt-get install -y nodejs + # Install Node.js dependencies + - "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" + # Build + - hugo --gc --minify + # Compress + - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec gzip -f -k {} \; + - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec brotli -f -k {} \; + artifacts: + paths: + - public + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH +{{% /code %}} + +## Push your Hugo website to GitLab + +Next, create a new repository on GitLab. It is *not* necessary to make the repository public. In addition, you might want to add `/public` to your .gitignore file, as there is no need to push compiled assets to GitLab or keep your output website in version control. + +```bash +# initialize new git repository +git init + +# add /public directory to our .gitignore file +echo "/public" >> .gitignore + +# commit and push code to master branch +git add . +git commit -m "Initial commit" +git remote add origin https://gitlab.com/YourUsername/your-hugo-site.git +git push -u origin master +``` + +## Wait for your page to build + +That's it! You can now follow the CI agent building your page at `https://gitlab.com///pipelines`. + +After the build has passed, your new website is available at `https://.gitlab.io//`. + +## Next steps + +GitLab supports using custom CNAME's and TLS certificates. For more details on GitLab Pages, see the [GitLab Pages setup documentation](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). + +[Quick Start]: /getting-started/quick-start/ diff --cc docs/content/en/hosting-and-deployment/hosting-on-netlify.md index 00cc03042,000000000..91d044755 mode 100644,000000..100644 --- a/docs/content/en/hosting-and-deployment/hosting-on-netlify.md +++ b/docs/content/en/hosting-and-deployment/hosting-on-netlify.md @@@ -1,145 -1,0 +1,145 @@@ +--- +title: Host on Netlify +description: Netlify can host your Hugo site with CDN, continuous deployment, 1-click HTTPS, an admin GUI, and its own CLI. +categories: [hosting and deployment] +keywords: [netlify,hosting,deployment] +menu: + docs: + parent: hosting-and-deployment +toc: true +--- + +[Netlify][netlify] provides continuous deployment services, global CDN, ultra-fast DNS, atomic deploys, instant cache invalidation, one-click SSL, a browser-based interface, a CLI, and many other features for managing your Hugo website. + +## Assumptions + +* You have an account with GitHub, GitLab, or Bitbucket. +* You have completed the [Quick Start] or have a Hugo website you are ready to deploy and share with the world. +* You do not already have a Netlify account. + +## Create a Netlify account + +Go to [app.netlify.com] and select your preferred signup method. This will likely be a hosted Git provider, although you also have the option to sign up with an email address. + +The following examples use GitHub, but other git providers will follow a similar process. + +![Screenshot of the homepage for app.netlify.com, containing links to the most popular hosted git solutions.](/images/hosting-and-deployment/hosting-on-netlify/netlify-signup.jpg) + +Selecting GitHub will bring up an authorization modal for authentication. Select "Authorize application." + +![Screenshot of the authorization popup for Netlify and GitHub.](/images/hosting-and-deployment/hosting-on-netlify/netlify-first-authorize.jpg) + +## Create a new site with continuous deployment + +You're now already a Netlify member and should be brought to your new dashboard. Select "New site from git." + +![Screenshot of the blank Netlify admin panel with no sites and highlighted 'add new site' button'](/images/hosting-and-deployment/hosting-on-netlify/netlify-add-new-site.jpg) + +Netlify will then start walking you through the steps necessary for continuous deployment. First, you'll need to select your git provider again, but this time you are giving Netlify added permissions to your repositories. + +![Screenshot of step 1 of create a new site for Netlify: selecting the git provider](/images/hosting-and-deployment/hosting-on-netlify/netlify-create-new-site-step-1.jpg) + +And then again with the GitHub authorization modal: + +![Screenshot of step 1 of create a new site for Netlify: selecting the git provider](/images/hosting-and-deployment/hosting-on-netlify/netlify-authorize-added-permissions.jpg) + +Select the repo you want to use for continuous deployment. If you have a large number of repositories, you can filter through them in real time using repo search: + +![Screenshot of step 1 of create a new site for Netlify: selecting the git provider](/images/hosting-and-deployment/hosting-on-netlify/netlify-create-new-site-step-2.jpg) + +Once selected, you'll be brought to a screen for basic setup. Here you can select the branch you want to publish, your [build command], and your publish (i.e. deploy) directory. The publish directory should mirror that of what you've set in your [site configuration], the default of which is `public`. The following steps assume you are publishing from the `master` branch. + +## Configure Hugo version in Netlify + +You can [set Hugo version](https://www.netlify.com/blog/2017/04/11/netlify-plus-hugo-0.20-and-beyond/) for your environments in `netlify.toml` file or set `HUGO_VERSION` as a build environment variable in the Netlify console. + +For production: + +{{< code file="netlify.toml" >}} +[context.production.environment] - HUGO_VERSION = "0.99.1" ++ HUGO_VERSION = "0.115.4" +{{< /code >}} + +For testing: + +{{< code file="netlify.toml" >}} +[context.deploy-preview.environment] - HUGO_VERSION = "0.99.1" ++ HUGO_VERSION = "0.115.4" +{{< /code >}} + +The Netlify configuration file can be a little hard to understand and get right for the different environment, and you may get some inspiration and tips from this site's `netlify.toml`: + +{{< readfile file="netlify.toml" highlight="toml" >}} + +## Build and deploy site + +In the Netlify console, selecting "Deploy site" will immediately take you to a terminal for your build:. + +![Animated gif of deploying a site to Netlify, including the terminal read out for the build.](/images/hosting-and-deployment/hosting-on-netlify/netlify-deploying-site.gif) + +Once the build is finished---this should only take a few seconds--you should now see a "Hero Card" at the top of your screen letting you know the deployment is successful. The Hero Card is the first element that you see in most pages. It allows you to see a quick summary of the page and gives access to the most common/pertinent actions and information. You'll see that the URL is automatically generated by Netlify. You can update the URL in "Settings." + +![Screenshot of successful deploy badge at the top of a deployments screen from within the Netlify admin.](/images/hosting-and-deployment/hosting-on-netlify/netlify-deploy-published.jpg) + +![Screenshot of homepage to https://hugo-netlify-example.netlify.com, which is mostly dummy text](/images/hosting-and-deployment/hosting-on-netlify/netlify-live-site.jpg) + +[Visit the live site][visit]. + +Now every time you push changes to your hosted git repository, Netlify will rebuild and redeploy your site. + +See [this blog post](https://www.netlify.com/blog/2017/04/11/netlify-plus-hugo-0.20-and-beyond/) for more details about how Netlify handles Hugo versions. + +## Use Hugo themes with Netlify + +The `git clone` method for installing themes is not supported by Netlify. If you were to use `git clone`, it would require you to recursively remove the `.git` subdirectory from the theme folder and would therefore prevent compatibility with future versions of the theme. + +A *better* approach is to install a theme as a proper git submodule. You can [read the GitHub documentation for submodules][ghsm] or those found on [Git's website][gitsm] for more information, but the command is similar to that of `git clone`: + +```txt +cd themes +git submodule add https://github.com// +``` + +It is recommended to only use stable versions of a theme (if it’s versioned) and always check the changelog. This can be done by checking out a specific release within the theme's directory. + +Switch to the theme's directory and list all available versions: + +```txt +cd themes/ +git tag +# exit with q +``` + +You can checkout a specific version as follows: + +```txt +git checkout tags/ +``` + +You can update a theme to the latest version by executing the following command in the *root* directory of your project: + +```txt +git submodule update --rebase --remote +``` + +## Next steps + +You now have a live website served over HTTPS, distributed through CDN, and configured for continuous deployment. Dig deeper into the Netlify documentation: + +1. [Using a Custom Domain] +2. [Setting up HTTPS on Custom Domains][httpscustom] +3. [Redirects and Rewrite Rules] + +[app.netlify.com]: https://app.netlify.com +[build command]: /getting-started/usage/#build-your-site +[site configuration]: /getting-started/configuration/ +[ghsm]: https://github.com/blog/2104-working-with-submodules +[gitsm]: https://git-scm.com/book/en/v2/Git-Tools-Submodules +[httpscustom]: https://www.netlify.com/docs/ssl/ +[hugoversions]: https://github.com/netlify/build-image/blob/master/Dockerfile#L216 +[netlify]: https://www.netlify.com/ +[netlifysignup]: https://app.netlify.com/signup +[Quick Start]: /getting-started/quick-start/ +[Redirects and Rewrite Rules]: https://www.netlify.com/docs/redirects/ +[Using a Custom Domain]: https://www.netlify.com/docs/custom-domains/ +[visit]: https://hugo-netlify-example.netlify.com diff --cc docs/content/en/installation/common/05-build-from-source.md index c0bd85515,000000000..7537882fd mode 100644,000000..100644 --- a/docs/content/en/installation/common/05-build-from-source.md +++ b/docs/content/en/installation/common/05-build-from-source.md @@@ -1,20 -1,0 +1,23 @@@ +## Build from source + - To build Hugo from source you must: ++To build the extended edition of Hugo from source you must: + +1. Install [Git] +1. Install [Go] version 1.19 or later - 1. Update your PATH environment variable as described in the [Go documentation] ++1. Install a C compiler, either [GCC] or [Clang] ++1. Update your `PATH` environment variable as described in the [Go documentation] + - > The install directory is controlled by the GOPATH and GOBIN environment variables. If GOBIN is set, binaries are installed to that directory. If GOPATH is set, binaries are installed to the bin subdirectory of the first directory in the GOPATH list. Otherwise, binaries are installed to the bin subdirectory of the default GOPATH ($HOME/go or %USERPROFILE%\go). ++> The install directory is controlled by the `GOPATH` and `GOBIN` environment variables. If `GOBIN` is set, binaries are installed to that directory. If `GOPATH` is set, binaries are installed to the bin subdirectory of the first directory in the `GOPATH` list. Otherwise, binaries are installed to the bin subdirectory of the default `GOPATH` (`$HOME/go` or `%USERPROFILE%\go`). + +Then build and test: + +```sh - go install -tags extended github.com/gohugoio/hugo@latest ++CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest +hugo version +``` + ++[Clang]: https://clang.llvm.org/ ++[GCC]: https://gcc.gnu.org/ +[Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git - [Go]: https://go.dev/doc/install +[Go documentation]: https://go.dev/doc/code#Command ++[Go]: https://go.dev/doc/install diff --cc docs/content/en/installation/linux.md index 11c6795f1,000000000..4056b987a mode 100644,000000..100644 --- a/docs/content/en/installation/linux.md +++ b/docs/content/en/installation/linux.md @@@ -1,141 -1,0 +1,143 @@@ +--- +title: Linux +description: Install Hugo on Linux. +categories: [installation] +menu: + docs: + parent: installation + weight: 30 +toc: true +weight: 30 +--- +{{% readfile file="/installation/common/01-editions.md" %}} + +{{% readfile file="/installation/common/02-prerequisites.md" %}} + +{{% readfile file="/installation/common/03-prebuilt-binaries.md" %}} + +## Package managers + +### Snap + +[Snap] is a free and open source package manager for Linux. Available for [most distributions], snap packages are simple to install and are automatically updated. + +The Hugo snap package is [strictly confined]. Strictly confined snaps run in complete isolation, up to a minimal access level that’s deemed always safe. The sites you create and build must be located within your home directory, or on removable media. + +This will install the extended edition of Hugo: + +```sh +sudo snap install hugo +``` + - To enable access to removable media: ++To enable or revoke access to removable media: + +```sh +sudo snap connect hugo:removable-media ++sudo snap disconnect hugo:removable-media +``` + - To revoke access to removable media: ++To enable or revoke access to SSH keys: + +```sh - sudo snap disconnect hugo:removable-media ++sudo snap connect hugo:ssh-keys ++sudo snap disconnect hugo:ssh-keys +``` + +[most distributions]: https://snapcraft.io/docs/installing-snapd +[strictly confined]: https://snapcraft.io/docs/snap-confinement +[Snap]: https://snapcraft.io/ + +{{% readfile file="/installation/common/homebrew.md" %}} + +## Repository packages + +Most Linux distributions maintain a repository for commonly installed applications. Please note that these repositories may not contain the [latest release]. + +[latest release]: https://github.com/gohugoio/hugo/releases/latest + +### Arch Linux + +Derivatives of the [Arch Linux] distribution of Linux include [EndeavourOS], [Garuda Linux], [Manjaro], and others. This will install the extended edition of Hugo: + +```sh +sudo pacman -S hugo +``` + +[Arch Linux]: https://archlinux.org/ +[EndeavourOS]: https://endeavouros.com/ +[Manjaro]: https://manjaro.org/ +[Garuda Linux]: https://garudalinux.org/ + +### Debian + +Derivatives of the [Debian] distribution of Linux include [elementary OS], [KDE neon], [Linux Lite], [Linux Mint], [MX Linux], [Pop!_OS], [Ubuntu], [Zorin OS], and others. This will install the extended edition of Hugo: + +```sh +sudo apt install hugo +``` + +You can also download Debian packages from the [latest release] page. + +[Debian]: https://www.debian.org/ +[elementary OS]: https://elementary.io/ +[KDE neon]: https://neon.kde.org/ +[Linux Lite]: https://www.linuxliteos.com/ +[Linux Mint]: https://linuxmint.com/ +[MX Linux]: https://mxlinux.org/ +[Pop!_OS]: https://pop.system76.com/ +[Ubuntu]: https://ubuntu.com/ +[Zorin OS]: https://zorin.com/os/ + +### Fedora + +Derivatives of the [Fedora] distribution of Linux include [CentOS], [Red Hat Enterprise Linux], and others. This will install the extended edition of Hugo: + + +```sh +sudo dnf install hugo +``` + +[CentOS]: https://www.centos.org/ +[Fedora]: https://getfedora.org/ +[Red Hat Enterprise Linux]: https://www.redhat.com/ + +### openSUSE + +Derivatives of the [openSUSE] distribution of Linux include [GeckoLinux], [Linux Karmada], and others. This will install the extended edition of Hugo: + + +```sh +sudo zypper install hugo +``` + +[GeckoLinux]: https://geckolinux.github.io/ +[Linux Karmada]: https://linuxkamarada.com/ +[openSUSE]: https://www.opensuse.org/ + +### Solus + +The [Solus] distribution of Linux includes Hugo in its package repository. This will install the _standard_ edition of Hugo: + +```sh +sudo eopkg install hugo +``` + +[Solus]: https://getsol.us/ + +{{% readfile file="/installation/common/04-docker.md" %}} + +{{% readfile file="/installation/common/05-build-from-source.md" %}} + +## Comparison + +||Prebuilt binaries|Package managers|Repository packages|Docker|Build from source +:--|:--:|:--:|:--:|:--:|:--: +Easy to install?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark: +Easy to upgrade?|:heavy_check_mark:|:heavy_check_mark:|varies|:heavy_check_mark:|:heavy_check_mark: +Easy to downgrade?|:heavy_check_mark:|:heavy_check_mark: [^1]|varies|:heavy_check_mark:|:heavy_check_mark: +Automatic updates?|:x:|varies [^2]|:x:|:x: [^3]|:x: +Latest version available?|:heavy_check_mark:|:heavy_check_mark:|varies|:heavy_check_mark:|:heavy_check_mark: + +[^1]: Easy if a previous version is still installed. +[^2]: Snap packages are automatically updated. Homebrew requires advanced configuration. +[^3]: Possible but requires advanced configuration. diff --cc docs/content/en/installation/windows.md index 9959f590a,000000000..92979d9f2 mode 100644,000000..100644 --- a/docs/content/en/installation/windows.md +++ b/docs/content/en/installation/windows.md @@@ -1,72 -1,0 +1,69 @@@ +--- +title: Windows +description: Install Hugo on Windows. +categories: [installation] +menu: + docs: + parent: installation + weight: 40 +toc: true +weight: 40 +--- +{{% readfile file="/installation/common/01-editions.md" %}} + +{{% readfile file="/installation/common/02-prerequisites.md" %}} + +{{% readfile file="/installation/common/03-prebuilt-binaries.md" %}} + +## Package managers + +### Chocolatey + +[Chocolatey] is a free and open source package manager for Windows. This will install the extended edition of Hugo: + +```sh +choco install hugo-extended +``` + +[Chocolatey]: https://chocolatey.org/ + +### Scoop + +[Scoop] is a free and open source package manager for Windows. This will install the extended edition of Hugo: + +```sh +scoop install hugo-extended +``` + +[Scoop]: https://scoop.sh/ + +### Winget + +[Winget] is Microsoft's official free and open source package manager for Windows. This will install the extended edition of Hugo: + +```sh +winget install Hugo.Hugo.Extended +``` + +[Winget]: https://learn.microsoft.com/en-us/windows/package-manager/ + +{{% readfile file="/installation/common/04-docker.md" %}} + +{{% readfile file="/installation/common/05-build-from-source.md" %}} + +{{% note %}} - When building the extended edition of Hugo from source on Windows, you will also need to install the [GCC compiler]. See these [detailed instructions]. - - [detailed instructions]: https://discourse.gohugo.io/t/41370 - [GCC compiler]: https://gcc.gnu.org/ ++See these [detailed instructions](https://discourse.gohugo.io/t/41370) to install GCC on Windows. +{{% /note %}} + +## Comparison + +||Prebuilt binaries|Package managers|Docker|Build from source +:--|:--:|:--:|:--:|:--:|:--: +Easy to install?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:| +Easy to upgrade?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark: +Easy to downgrade?|:heavy_check_mark:|:heavy_check_mark: [^2]|:heavy_check_mark:|:heavy_check_mark: +Automatic updates?|:x:|:x: [^1]|:x: [^1]|:x: +Latest version available?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark: + +[^1]: Possible but requires advanced configuration. +[^2]: Easy if a previous version is still installed. diff --cc docs/content/en/news/0.25-relnotes/index.md index 6ceef445d,000000000..5ed0a2bc1 mode 100644,000000..100644 --- a/docs/content/en/news/0.25-relnotes/index.md +++ b/docs/content/en/news/0.25-relnotes/index.md @@@ -1,76 -1,0 +1,74 @@@ +--- +date: 2017-07-07T17:53:58-04:00 +categories: ["Releases"] +description: "Hugo 0.25 automatically opens the page you're working on in the browser" +link: "" +title: "Hugo 0.25" +aliases: [/0-25/] +--- + +Hugo `0.25` is the **Kinder Surprise**: It automatically opens the page you're working on in the browser, it adds full `AND` and `OR` support in page queries, and you can now have templates per language. + - ![Hugo Open on Save](https://cdn-standard5.discourse.org/uploads/gohugo/optimized/2X/6/622088d4a8eacaf62bbbaa27dab19d789e10fe09_1_690x345.gif "Hugo Open on Save") - +If you start with `hugo server --navigateToChanged`, Hugo will navigate to the relevant page on save (see animated GIF). This is extremely useful for site-wide edits. Another very useful feature in this version is the added support for `AND` (`intersect`) and `OR` (`union`) filters when combined with `where`. + +Example: + +``` +{{ $pages := where .Site.RegularPages "Type" "not in" (slice "page" "about") }} +{{ $pages := $pages | union (where .Site.RegularPages "Params.pinned" true) }} +{{ $pages := $pages | intersect (where .Site.RegularPages "Params.images" "!=" nil) }} +``` + +The above fetches regular pages not of `page` or `about` type unless they are pinned. And finally, we exclude all pages with no `images` set in Page params. + +This release represents **36 contributions by 12 contributors** to the main Hugo code base. [@bep](https://github.com/bep) still leads the Hugo development with his witty Norwegian humor, and once again contributed a significant amount of additions. But also a big shoutout to [@yihui](https://github.com/yihui), [@anthonyfok](https://github.com/anthonyfok), and [@kropp](https://github.com/kropp) for their ongoing contributions. And as always a big thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) for his relentless work on keeping the documentation and the themes site in pristine condition. + +Hugo now has: + +* 18209+ [stars](https://github.com/gohugoio/hugo/stargazers) +* 455+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors) +* 168+ [themes](http://themes.gohugo.io/) + +## Enhancements + +### Templates + +* Add `Pages` support to `intersect` (`AND`) and `union`(`OR`). This makes the `where` template func even more powerful. [ccdd08d5](https://github.com/gohugoio/hugo/commit/ccdd08d57ab64441e93d6861ae126b5faacdb92f) [@bep](https://github.com/bep) [#3174](https://github.com/gohugoio/hugo/issues/3174) +* Add `math.Log` function. This is very handy for creating tag clouds. [34c56677](https://github.com/gohugoio/hugo/commit/34c566773a1364077e1397daece85b22948dc721) [@artem-sidorenko](https://github.com/artem-sidorenko) +* Add `WebP` images support [8431c8d3](https://github.com/gohugoio/hugo/commit/8431c8d39d878c18c6b5463d9091a953608df10b) [@bep](https://github.com/bep) [#3529](https://github.com/gohugoio/hugo/issues/3529) +* Only show post's own keywords in schema.org [da72805a](https://github.com/gohugoio/hugo/commit/da72805a4304a57362e8e79a01cc145767b027c5) [@brunoamaral](https://github.com/brunoamaral) [#2635](https://github.com/gohugoio/hugo/issues/2635)[#2646](https://github.com/gohugoio/hugo/issues/2646) +* Simplify the `Disqus` template a little bit (#3655) [eccb0647](https://github.com/gohugoio/hugo/commit/eccb0647821e9db20ba9800da1b4861807cc5205) [@yihui](https://github.com/yihui) +* Improve the built-in Disqus template (#3639) [2e1e4934](https://github.com/gohugoio/hugo/commit/2e1e4934b60ce8081a7f3a79191ed204f3098481) [@yihui](https://github.com/yihui) + +### Output + +* Support templates per site/language. This is for both regular templates and shortcode templates. [aa6b1b9b](https://github.com/gohugoio/hugo/commit/aa6b1b9be7c9d7322333893b642aaf8c7a5f2c2e) [@bep](https://github.com/bep) [#3360](https://github.com/gohugoio/hugo/issues/3360) + +### Core + +* Extend the sections API [a1d260b4](https://github.com/gohugoio/hugo/commit/a1d260b41a6673adef679ec4e262c5f390432cf5) [@bep](https://github.com/bep) [#3591](https://github.com/gohugoio/hugo/issues/3591) +* Make `.Site.Sections` return the top level sections [dd9b1baa](https://github.com/gohugoio/hugo/commit/dd9b1baab0cb860a3eb32fd9043bac18cab3f9f0) [@bep](https://github.com/bep) [#3591](https://github.com/gohugoio/hugo/issues/3591) +* Render `404.html` for all languages [41805dca](https://github.com/gohugoio/hugo/commit/41805dca9e40e9b0952e04d06074e6fc91140495) [@mitchchn](https://github.com/mitchchn) [#3598](https://github.com/gohugoio/hugo/issues/3598) + +### Other + +* Support human-readable `YAML` boolean values in `undraft` [1039356e](https://github.com/gohugoio/hugo/commit/1039356edf747f044c989a5bc0e85d792341ed5d) [@kropp](https://github.com/kropp) +* `hugo import jekyll` support nested `_posts` directories [7ee1f25e](https://github.com/gohugoio/hugo/commit/7ee1f25e9ef3be8f99c171e8e7982f4f82c13e16) [@coderzh](https://github.com/coderzh) [#1890](https://github.com/gohugoio/hugo/issues/1890)[#1911](https://github.com/gohugoio/hugo/issues/1911) +* Update `Dockerfile` and add Docker optimizations [118f8f7c](https://github.com/gohugoio/hugo/commit/118f8f7cf22d756d8a894ff93551974a806f2155) [@ellerbrock](https://github.com/ellerbrock) +* Add Blackfriday `joinLines` extension support (#3574) [a5440496](https://github.com/gohugoio/hugo/commit/a54404968a4b36579797f2e7ff7f5eada94866d9) [@choueric](https://github.com/choueric) +* add `--initial-header-level=2` to rst2html (#3528) [bfce30d8](https://github.com/gohugoio/hugo/commit/bfce30d85972c27c27e8a2caac9db6315f813298) [@frankbraun](https://github.com/frankbraun) +* Support open "current content page" in browser [c825a731](https://github.com/gohugoio/hugo/commit/c825a7312131b4afa67ee90d593640dee3525d98) [@bep](https://github.com/bep) [#3643](https://github.com/gohugoio/hugo/issues/3643) +* Make `--navigateToChanged` more robust on Windows [30e14cc3](https://github.com/gohugoio/hugo/commit/30e14cc31678ddc204b082ab362f86b6b8063881) [@anthonyfok](https://github.com/anthonyfok) [#3645](https://github.com/gohugoio/hugo/issues/3645) +* Remove the docs submodule [31393f60](https://github.com/gohugoio/hugo/commit/31393f6024416ea1b2e61d1080dfd7104df36eda) [@bep](https://github.com/bep) [#3647](https://github.com/gohugoio/hugo/issues/3647) +* Use `example.com` as homepage for new theme [aff1ac32](https://github.com/gohugoio/hugo/commit/aff1ac3235b6c075d01f7237addf44fecdd36d82) [@anthonyfok](https://github.com/anthonyfok) + +## Fixes + +### Templates + +* Fix `in` function for JSON arrays [d12cf5a2](https://github.com/gohugoio/hugo/commit/d12cf5a25df00fa16c59f0b2ae282187a398214c) [@bep](https://github.com/bep) [#1468](https://github.com/gohugoio/hugo/issues/1468) + +### Other + +* Fix handling of `JSON` front matter with escaped quotes [e10e51a0](https://github.com/gohugoio/hugo/commit/e10e51a00827b9fdc1bee51439fef05afc529831) [@bep](https://github.com/bep) [#3661](https://github.com/gohugoio/hugo/issues/3661) +* Fix typo in code comment [56d82aa0](https://github.com/gohugoio/hugo/commit/56d82aa025f4d2edb1dc6315132cd7ab52df649a) [@dvic](https://github.com/dvic) diff --cc docs/content/en/templates/homepage.md index 5fe6902d3,000000000..a176a51f2 mode 100644,000000..100644 --- a/docs/content/en/templates/homepage.md +++ b/docs/content/en/templates/homepage.md @@@ -1,65 -1,0 +1,65 @@@ +--- +title: Homepage template +description: The homepage of a website is often formatted differently than the other pages. For this reason, Hugo makes it easy for you to define your new site's homepage as a unique template. +categories: [templates] +keywords: [homepage] +menu: + docs: + parent: templates + weight: 70 +weight: 70 +aliases: [/layout/homepage/,/templates/homepage-template/] +toc: true +--- + +Homepage is a `Page` and therefore has all the [page variables][pagevars] and [site variables][sitevars] available for use. + +{{% note %}} +The homepage template is the *only* required template for building a site and therefore useful when bootstrapping a new site and template. It is also the only required template if you are developing a single-page website. +{{% /note %}} + +{{< youtube ut1xtRZ1QOA >}} + +## Homepage template lookup order + +See [Template Lookup](/templates/lookup-order/). + +## Add content and front matter to the homepage + +The homepage, similar to other [list pages in Hugo][lists], accepts content and front matter from an `_index.md` file. This file should live at the root of your `content` folder (i.e., `content/_index.md`). You can then add body copy and metadata to your homepage the way you would any other content file. + +See the homepage template below or [Content Organization][contentorg] for more information on the role of `_index.md` in adding content and front matter to list pages. + +## Example homepage template + +The following is an example of a homepage template that uses [partial][partials], [base] templates, and a content file at `content/_index.md` to populate the `{{ .Title }}` and `{{ .Content }}` [page variables][pagevars]. + +{{< code file="layouts/index.html" >}} +{{ define "main" }} +
+
+

{{ .Title }}

+ {{ with .Params.subtitle }} - {{ . }} ++ {{ . }} + {{ end }} +
+
+ + {{ .Content }} +
+
+ {{ range first 10 .Site.RegularPages }} - {{ .Render "summary" }} ++ {{ .Render "summary" }} + {{ end }} +
+
+{{ end }} +{{< /code >}} + +[base]: /templates/base/ +[contentorg]: /content-management/organization/ +[lists]: /templates/lists/ +[lookup]: /templates/lookup-order/ +[pagevars]: /variables/page/ +[partials]: /templates/partials/ +[sitevars]: /variables/site/ diff --cc docs/content/en/templates/internal.md index 828244fa0,000000000..ee0d7258d mode 100644,000000..100644 --- a/docs/content/en/templates/internal.md +++ b/docs/content/en/templates/internal.md @@@ -1,232 -1,0 +1,220 @@@ +--- +title: Internal templates +description: Hugo ships with a group of boilerplate templates that cover the most common use cases for static websites. +categories: [templates] +keywords: [internal, analytics,] +menu: + docs: + parent: templates + weight: 190 +weight: 190 +toc: true +--- + + +{{% note %}} +While the following internal templates are called similar to partials, they do *not* observe the partial template lookup order. +{{% /note %}} + +## Google Analytics + - Hugo ships with internal templates supporting Google Analytics, both [Google Analytics 4][GA4] (GA4) and Universal Analytics. ++Hugo ships with an internal template supporting [Google Analytics 4][GA4] (GA4). + - **Note:** Universal Analytics are deprecated. For details, see [Universal Analytics will be going away]. ++**Note:** Universal Analytics are [deprecated]. + +[GA4]: https://support.google.com/analytics/answer/10089681 - [Universal Analytics will be going away]: https://support.google.com/analytics/answer/11583528 ++[deprecated]: https://support.google.com/analytics/answer/11583528 + +### Configure Google Analytics + +Provide your tracking ID in your configuration file: + +**Google Analytics 4 (gtag.js)** +{{< code-toggle file="hugo" >}} +googleAnalytics = "G-MEASUREMENT_ID" +{{}} + - **Google Universal Analytics (analytics.js)** - {{< code-toggle file="hugo" >}} - googleAnalytics = "UA-PROPERTY_ID" - {{}} - +### Use the Google Analytics template + - You can then include the Google Analytics internal template: - - ```go-html-template - {{ template "_internal/google_analytics_async.html" . }} - ``` - - **Note:** The async template is _not_ suitable for Google Analytics 4. ++Include the Google Analytics internal template in your templates where you want the code to appear: + +```go-html-template +{{ template "_internal/google_analytics.html" . }} +``` + - If you want to create your own template, you can access the configured ID with `{{ site.Config.Services.GoogleAnalytics.ID }}`. ++To create your own template, access the configured ID with `{{ site.Config.Services.GoogleAnalytics.ID }}`. + +## Disqus + - Hugo also ships with an internal template for [Disqus comments][disqus], a popular commenting system for both static and dynamic websites. In order to effectively use Disqus, you will need to secure a Disqus "shortname" by [signing up for the free service][disqussignup]. ++Hugo also ships with an internal template for [Disqus comments][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][disqussignup]. + +### Configure Disqus + - To use Hugo's Disqus template, you first need to set a single configuration value: ++To use Hugo's Disqus template, first set up a single configuration value: + +{{< code-toggle file="hugo" >}} +disqusShortname = "your-disqus-shortname" +{{}} + - You also have the option to set the following in the front matter for a given piece of content: ++You can also set the following in the front matter for a given piece of content: + +* `disqus_identifier` +* `disqus_title` +* `disqus_url` + +### Use the Disqus template + - To add Disqus, include the following line in templates where you want your comments to appear: ++To add Disqus, include the following line in the templates where you want your comments to appear: + +```go-html-template +{{ template "_internal/disqus.html" . }} +``` + +A `.Site.DisqusShortname` variable is also exposed from the configuration. + +### Conditional loading of Disqus comments + +Users have noticed that enabling Disqus comments when running the Hugo web server on `localhost` (i.e. via `hugo server`) causes the creation of unwanted discussions on the associated Disqus account. + +You can create the following `layouts/partials/disqus.html`: + +{{< code file="layouts/partials/disqus.html" >}} +
+ + +comments powered by Disqus +{{< /code >}} + +The `if` statement skips the initialization of the Disqus comment injection when you are running on `localhost`. + +You can then render your custom Disqus partial template as follows: + +```go-html-template +{{ partial "disqus.html" . }} +``` + +## Open Graph + +An internal 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. + +### Configure Open Graph + +Hugo's Open Graph template is configured using a mix of configuration variables and [front-matter](/content-management/front-matter/) on individual pages. + +{{< code-toggle file="hugo" >}} +[params] + title = "My cool site" + images = ["site-feature-image.jpg"] + description = "Text about my cool site" +[taxonomies] + series = "series" +{{}} + +{{< code-toggle file="content/blog/my-post" >}} +title = "Post title" +description = "Text about this post" +date = "2006-01-02" +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. + +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`). + +### Use the Open Graph template + +To add Open Graph metadata, include the following line between the `` tags in your templates: + +```go-html-template +{{ template "_internal/opengraph.html" . }} +``` + +## Twitter Cards + +An internal template for [Twitter Cards](https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards), +metadata used to attach rich media to Tweets linking to your site. + +### Configure Twitter Cards + +Hugo's Twitter Card template is configured using a mix of configuration variables and [front-matter](/content-management/front-matter/) 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" >}} +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 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. + +The `.Site.Social.twitter` variable is exposed from the configuration as the value for `twitter:site`. + +{{< code-toggle file="hugo" >}} +[social] + twitter = "GoHugoIO" +{{}} + +NOTE: The `@` will be added for you + +```html + +``` + +### Use the Twitter Cards template + +To add Twitter card metadata, include the following line immediately after the `` element in your templates: + +```go-html-template +{{ template "_internal/twitter_cards.html" . }} +``` + +## The internal templates + +The code for these templates is located [here](https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates). + +* `_internal/disqus.html` +* `_internal/google_analytics.html` - * `_internal/google_analytics_async.html` +* `_internal/opengraph.html` +* `_internal/pagination.html` +* `_internal/schema.html` +* `_internal/twitter_cards.html` + +[disqus]: https://disqus.com +[disqussignup]: https://disqus.com/profile/signup/ diff --cc docs/content/en/templates/lists/index.md index 204cbcbcc,000000000..ec397c32b mode 100644,000000..100644 --- a/docs/content/en/templates/lists/index.md +++ b/docs/content/en/templates/lists/index.md @@@ -1,598 -1,0 +1,598 @@@ +--- +title: Lists of content in Hugo +linkTitle: List templates +description: Lists have a specific meaning and usage in Hugo when it comes to rendering your site homepage, section page, taxonomy list, or taxonomy terms list. +categories: [templates] +keywords: [lists,sections,rss,taxonomies,terms] +menu: + docs: + parent: templates + weight: 60 +weight: 60 +aliases: [/templates/list/,/layout/indexes/] +toc: true +--- + +## What is a list page template? + +{{< youtube 8b2YTSMdMps >}} + +A list page template is a template used to render multiple pieces of content in a single HTML page. The exception to this rule is the homepage, which is still a list but has its own [dedicated template][homepage]. + +Hugo uses the term *list* in its truest sense; i.e. a sequential arrangement of material, especially in alphabetical or numerical order. Hugo uses list templates on any output HTML page where content is traditionally listed: + +* [Home page](/templates/homepage) +* [Section pages](/templates/section-templates) +* [Taxonomy pages](/templates/taxonomy-templates) +* [Taxonomy term pages](/templates/taxonomy-templates) +* [RSS feeds](/templates/rss) +* [Sitemaps](/templates/sitemap-template) + +For template lookup order, see [Template Lookup](/templates/lookup-order/). + +The idea of a list page comes from the [hierarchical mental model of the web][mentalmodel] and is best demonstrated visually: + +[![Image demonstrating a hierarchical website sitemap.](site-hierarchy.svg)](site-hierarchy.svg) + +## List defaults + +### Default templates + +Since section lists and taxonomy lists (N.B., *not* [taxonomy terms lists][taxterms]) are both *lists* with regards to their templates, both have the same terminating default of `_default/list.html` or `themes//layouts/_default/list.html` in their lookup order. In addition, both [section lists][sectiontemps] and [taxonomy lists][taxlists] have their own default list templates in `_default`. + +See [Template Lookup Order](/templates/lookup-order/) for the complete reference. + +## Add content and front matter to list pages + +Since v0.18, [everything in Hugo is a `Page`][bepsays]. This means list pages and the homepage can have associated content files (i.e. `_index.md`) that contain page metadata (i.e., front matter) and content. + +This new model allows you to include list-specific front matter via `.Params` and also means that list templates (e.g., `layouts/_default/list.html`) have access to all [page variables][pagevars]. + +{{% note %}} +It is important to note that all `_index.md` content files will render according to a *list* template and not according to a [single page template](/templates/single-page-templates/). +{{% /note %}} + +### Example project directory + +The following is an example of a typical Hugo project directory's content: + +```txt +. +... +├── content +| ├── posts +| | ├── _index.md +| | ├── post-01.md +| | └── post-02.md +| └── quote +| | ├── quote-01.md +| | └── quote-02.md +... +``` + +Using the above example, let's assume you have the following in `content/posts/_index.md`: + +{{< code file="content/posts/_index.md" >}} +--- +title: My Go Journey +date: 2017-03-23 +publishdate: 2017-03-24 +--- + +I decided to start learning Go in March 2017. + +Follow my journey through this new blog. +{{< /code >}} + +You can now access this `_index.md`'s' content in your list template: + +{{< code file="layouts/_default/list.html" >}} +{{ define "main" }} +
+
+
+

{{ .Title }}

+
+ + {{ .Content }} +
+ +
+{{ end }} +{{< /code >}} + +This above will output the following HTML: + +{{< code file="example.com/posts/index.html" copy=false >}} + +
+
+
+

My Go Journey

+
+

I decided to start learning Go in March 2017.

+

Follow my journey through this new blog.

+
+ +
+ +{{< /code >}} + +### List pages without `_index.md` + +You do *not* have to create an `_index.md` file for every list page (i.e. section, taxonomy, taxonomy terms, etc) or the homepage. If Hugo does not find an `_index.md` within the respective content section when rendering a list template, the page will be created but with no `{{ .Content }}` and only the default values for `.Title` etc. + +Using this same `layouts/_default/list.html` template and applying it to the `quotes` section above will render the following output. Note that `quotes` does not have an `_index.md` file to pull from: + +{{< code file="example.com/quote/index.html" copy=false >}} + +
+
+
+ +

Quotes

+
+
+ +
+ +{{< /code >}} + +{{% note %}} +The default behavior of Hugo is to pluralize list titles; hence the inflection of the `quote` section to "Quotes" when called with the `.Title` [page variable](/variables/page/). You can change this via the `pluralizeListTitles` directive in your [site configuration](/getting-started/configuration/). +{{% /note %}} + +## Example list templates + +### Section template + +This list template has been modified slightly from a template originally used in [spf13.com](https://spf13.com/). It makes use of [partial templates][partials] for the chrome of the rendered page rather than using a [base template][base]. The examples that follow also use the [content view templates][views] `li.html` or `summary.html`. + +{{< code file="layouts/section/posts.html" >}} +{{ partial "header.html" . }} +{{ partial "subheader.html" . }} +
+
-

{{ .Title }}

-
    - - {{ range .Pages }} - {{ .Render "li" }} - {{ end }} -
++

{{ .Title }}

++
    ++ ++ {{ range .Pages }} ++ {{ .Render "li" }} ++ {{ end }} ++
+
+
+{{ partial "footer.html" . }} +{{< /code >}} + +### Taxonomy template + +{{< code file="layouts/_default/taxonomy.html" >}} +{{ define "main" }} +
+
-

{{ .Title }}

- ++

{{ .Title }}

++ + {{ range .Pages }} - {{ .Render "summary" }} ++ {{ .Render "summary" }} + {{ end }} +
+
+{{ end }} +{{< /code >}} + +## Order content + +Hugo lists render the content based on metadata you provide in [front matter]. In addition to sane defaults, Hugo also ships with multiple methods to make quick work of ordering content inside list templates: + +### Default: Weight > Date > LinkTitle > FilePath + +{{< code file="layouts/partials/default-order.html" >}} +
    + {{ range .Pages }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By weight + +Lower weight gets higher precedence. So content with lower weight will come first. + +{{< code file="layouts/partials/by-weight.html" >}} +
    + {{ range .Pages.ByWeight }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By date + +{{< code file="layouts/partials/by-date.html" >}} +
    + + {{ range .Pages.ByDate }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By publish date + +{{< code file="layouts/partials/by-publish-date.html" >}} +
    + + {{ range .Pages.ByPublishDate }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By expiration date + +{{< code file="layouts/partials/by-expiry-date.html" >}} +
    + {{ range .Pages.ByExpiryDate }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By last modified date + +{{< code file="layouts/partials/by-last-mod.html" >}} +
    + + {{ range .Pages.ByLastmod }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By length + +{{< code file="layouts/partials/by-length.html" >}} +
    + + {{ range .Pages.ByLength }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By title + +{{< code file="layouts/partials/by-title.html" >}} +
    + + {{ range .Pages.ByTitle }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By link title + +{{< code file="layouts/partials/by-link-title.html" >}} +
    + + {{ range .Pages.ByLinkTitle }} +
  • +

    {{ .LinkTitle }}

    + +
  • + {{ end }} +
+{{< /code >}} + +### By page parameter + +Order based on the specified front matter parameter. Content that does not have the specified front matter field will use the site's `.Site.Params` default. If the parameter is not found at all in some entries, those entries will appear together at the end of the ordering. + +{{< code file="layouts/partials/by-rating.html" >}} + +{{ range (.Pages.ByParam "rating") }} + +{{ end }} +{{< /code >}} + +If the targeted front matter field is nested beneath another field, you can access the field using dot notation. + +{{< code file="layouts/partials/by-nested-param.html" >}} +{{ range (.Pages.ByParam "author.last_name") }} + +{{ end }} +{{< /code >}} + +### Reverse order + +Reversing order can be applied to any of the above methods. The following uses `ByDate` as an example: + +{{< code file="layouts/partials/by-date-reverse.html" >}} +
    + {{ range .Pages.ByDate.Reverse }} +
  • +

    {{ .Title }}

    + +
  • + {{ end }} +
+{{< /code >}} + +## Group content + +Hugo provides some functions for grouping pages by Section, Type, Date, etc. + +### By page field + +{{< code file="layouts/partials/by-page-field.html" >}} + +{{ range .Pages.GroupBy "Section" }} +

{{ .Key }}

+
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .Date.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +In the above example, you may want `{{ .Title }}` to point the `title` field you have added to your `_index.md` file instead. You can access this value using the [`.GetPage` function][getpage]: + +{{< code file="layouts/partials/by-page-field.html" >}} + +{{ range .Pages.GroupBy "Section" }} + +{{ with $.Site.GetPage "section" .Key }} +

{{ .Title }}

+{{ else }} + +

{{ .Key | title }}

+{{ end }} +
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .Date.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +### By date + +{{< code file="layouts/partials/by-page-date.html" >}} + +{{ range .Pages.GroupByDate "2006-01" }} +

{{ .Key }}

+
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .Date.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +{{< new-in "0.97.0" >}} `GroupByDate` accepts the same time layouts as in [time.Format](/functions/dateformat/) and The `.Key` in the result will be localized for the current language. + +### By publish date + +{{< code file="layouts/partials/by-page-publish-date.html" >}} + +{{ range .Pages.GroupByPublishDate "2006-01" }} +

{{ .Key }}

+
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .PublishDate.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +{{< new-in "0.97.0" >}} `GroupByDate` accepts the same time layouts as in [time.Format](/functions/dateformat/) and The `.Key` in the result will be localized for the current language. + + +### By expiration date + +{{< code file="layouts/partials/by-page-expiry-date.html" >}} + +{{ range .Pages.GroupByExpiryDate "2006-01" }} +

{{ .Key }}

+
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .ExpiryDate.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +{{< new-in "0.97.0" >}} `GroupByDate` accepts the same time layouts as in [time.Format](/functions/dateformat/) and The `.Key` in the result will be localized for the current language. + +### By last modified date + +{{< code file="layouts/partials/by-page-lastmod.html" >}} + +{{ range .Pages.GroupByLastmod "2006-01" }} +

{{ .Key }}

+
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .Lastmod.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +{{< new-in "0.97.0" >}} `GroupByDate` accepts the same time layouts as in [time.Format](/functions/dateformat/) and The `.Key` in the result will be localized for the current language. + +### By page parameter + +{{< code file="layouts/partials/by-page-param.html" >}} + +{{ range .Pages.GroupByParam "param_key" }} +

{{ .Key }}

+
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .Date.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +### By page parameter in date format + +The following template takes grouping by `date` a step further and uses Go's layout string. See the [`Format` function] for more examples of how to use Go's layout string to format dates in Hugo. + +{{< code file="layouts/partials/by-page-param-as-date.html" >}} + +{{ range .Pages.GroupByParamDate "param_key" "2006-01" }} +

{{ .Key }}

+
    + {{ range .Pages }} +
  • + {{ .Title }} +
    {{ .Date.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +### Reverse key order + +Ordering of groups is performed by keys in alphanumeric order (A–Z, 1–100) and in reverse chronological order (i.e., with the newest first) for dates. + +While these are logical defaults, they are not always the desired order. There are two different syntaxes to change Hugo's default ordering for groups, both of which work the same way. + +#### 1. Adding the reverse method + +```go-html-template +{{ range (.Pages.GroupBy "Section").Reverse }} +``` + +```go-html-template +{{ range (.Pages.GroupByDate "2006-01").Reverse }} +``` + +#### 2. Providing the alternate direction + +```go-html-template +{{ range .Pages.GroupByDate "2006-01" "asc" }} +``` + +```go-html-template +{{ range .Pages.GroupBy "Section" "desc" }} +``` + +### Order within groups + +Because Grouping returns a `{{ .Key }}` and a slice of pages, all the ordering methods listed above are available. + +Here is the ordering for the example that follows: + +1. Content is grouped by month according to the `date` field in front matter. +2. Groups are listed in ascending order (i.e., the oldest groups first) +3. Pages within each respective group are ordered alphabetically according to the `title`. + +{{< code file="layouts/partials/by-group-by-page.html" >}} +{{ range .Pages.GroupByDate "2006-01" "asc" }} +

{{ .Key }}

+
    + {{ range .Pages.ByTitle }} +
  • + {{ .Title }} +
    {{ .Date.Format "Mon, Jan 2, 2006" }}
    +
  • + {{ end }} +
+{{ end }} +{{< /code >}} + +## Filtering and limiting lists + +Sometimes you only want to list a subset of the available content. A +common is to only display posts from [**main sections**][mainsections] +on the blog's homepage. + +See the documentation on [`where` function][wherefunction] and +[`first` function][firstfunction] for further details. + +[base]: /templates/base/ +[bepsays]: https://bepsays.com/en/2016/12/19/hugo-018/ +[directorystructure]: /getting-started/directory-structure/ +[`Format` function]: /functions/format/ +[front matter]: /content-management/front-matter/ +[getpage]: /functions/getpage/ +[homepage]: /templates/homepage/ +[homepage]: /templates/homepage/ +[mentalmodel]: https://webstyleguide.com/wsg3/3-information-architecture/3-site-structure.html +[pagevars]: /variables/page/ +[partials]: /templates/partials/ +[RSS 2.0]: https://cyber.harvard.edu/rss/rss.html "RSS 2.0 Specification" +[rss]: /templates/rss/ +[sections]: /content-management/sections/ +[sectiontemps]: /templates/section-templates/ +[sitevars]: /variables/site/ +[taxlists]: /templates/taxonomy-templates/#taxonomy-list-templates +[taxterms]: /templates/taxonomy-templates/#taxonomy-terms-templates +[taxvars]: /variables/taxonomy/ +[views]: /templates/views/ +[wherefunction]: /functions/where/ +[firstfunction]: /functions/first/ +[mainsections]: /functions/where/#mainsections diff --cc docs/content/en/templates/section-templates.md index db8ffd667,000000000..55a6c3004 mode 100644,000000..100644 --- a/docs/content/en/templates/section-templates.md +++ b/docs/content/en/templates/section-templates.md @@@ -1,110 -1,0 +1,110 @@@ +--- +title: Section page templates +linkTitle: Section templates +description: Templates used for section pages are **lists** and therefore have all the variables and methods available to list pages. +categories: [templates] +keywords: [lists,sections,templates] +menu: + docs: + parent: templates + weight: 80 +weight: 80 +aliases: [/templates/sections/] +toc: true +--- + +## Add content and front matter to section templates + +To effectively leverage section page templates, you should first understand Hugo's [content organization](/content-management/organization/) and, specifically, the purpose of `_index.md` for adding content and front matter to section and other list pages. + +## Section template lookup order + +See [Template Lookup](/templates/lookup-order/). + +## Page kinds + +Every `Page` in Hugo has a `.Kind` attribute. + +{{% page-kinds %}} + +## `.Site.GetPage` with sections + +`Kind` can easily be combined with the [`where` function][where] in your templates to create kind-specific lists of content. This method is ideal for creating lists, but there are times where you may want to fetch just the index page of a single section via the section's path. + +The [`.GetPage` function][getpage] looks up an index page of a given `Kind` and `path`. + +You can call `.Site.GetPage` with two arguments: `kind` (one of the valid values +of `Kind` from above) and `kind value`. + +Examples: + +- `{{ .Site.GetPage "section" "posts" }}` +- `{{ .Site.GetPage "page" "search" }}` + +## Example: creating a default section template + +{{< code file="layouts/_default/section.html" >}} +{{ define "main" }} +
- {{ .Content }} -
    - {{ range .Paginator.Pages }} -
  • {{ .Title }} -
    - {{ partial "summary.html" . }} -
    -
  • - {{ end }} -
- {{ partial "pagination.html" . }} ++ {{ .Content }} ++
    ++ {{ range .Paginator.Pages }} ++
  • {{ .Title }} ++
    ++ {{ partial "summary.html" . }} ++
    ++
  • ++ {{ end }} ++
++ {{ partial "pagination.html" . }} +
+{{ end }} +{{< /code >}} + +### Example: using `.Site.GetPage` + +The `.Site.GetPage` example that follows assumes the following project directory structure: + +```txt +. +└── content + ├── blog + │   ├── _index.md # "title: My Hugo Blog" in the front matter + │   ├── post-1.md + │   ├── post-2.md + │   └── post-3.md + └── events #Note there is no _index.md file in "events" + ├── event-1.md + └── event-2.md +``` + +`.Site.GetPage` will return `nil` if no `_index.md` page is found. Therefore, if `content/blog/_index.md` does not exist, the template will output the section name: + +```go-html-template +

{{ with .Site.GetPage "section" "blog" }}{{ .Title }}{{ end }}

+``` + +Since `blog` has a section index page with front matter at `content/blog/_index.md`, the above code will return the following result: + +```html +

My Hugo Blog

+``` + +If we try the same code with the `events` section, however, Hugo will default to the section title because there is no `content/events/_index.md` from which to pull content and front matter: + +```go-html-template +

{{ with .Site.GetPage "section" "events" }}{{ .Title }}{{ end }}

+``` + +Which then returns the following: + +```html +

Events

+``` + +[contentorg]: /content-management/organization/ +[getpage]: /functions/getpage/ +[lists]: /templates/lists/ +[lookup]: /templates/lookup-order/ +[where]: /functions/where/ +[sections]: /content-management/sections/ diff --cc docs/content/en/templates/shortcode-templates.md index f293b6d52,000000000..6a6700380 mode 100644,000000..100644 --- a/docs/content/en/templates/shortcode-templates.md +++ b/docs/content/en/templates/shortcode-templates.md @@@ -1,409 -1,0 +1,415 @@@ +--- +title: Create your own shortcodes +linkTitle: Shortcode templates +description: You can extend Hugo's built-in shortcodes by creating your own using the same templating syntax as that for single and list pages. +categories: [templates] +keywords: [shortcodes,templates] +menu: + docs: + parent: templates + weight: 130 +weight: 130 +toc: true +--- + +Shortcodes are a means to consolidate templating into small, reusable snippets that you can embed directly inside your content. In this sense, you can think of shortcodes as the intermediary between [page and list templates][templates] and [basic content files]. + +{{% note %}} +Hugo also ships with built-in shortcodes for common use cases. (See [Content Management: Shortcodes](/content-management/shortcodes/).) +{{% /note %}} + +## Create custom shortcodes + +Hugo's built-in 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 of your [source organization]. 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 subfolders, 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` + +### Positional vs. named parameters + +You can create shortcodes using the following types of parameters: + +* Positional parameters +* Named parameters +* Positional *or* named parameters (i.e, "flexible") + +In shortcodes with positional parameters, the order of the parameters is important. If a shortcode has a single required value (e.g., the `youtube` shortcode below), positional parameters work very well and require less typing from content authors. + +For more complex layouts with multiple or optional parameters, named parameters work best. While less terse, named parameters require less memorization from a content author and can be added in a shortcode declaration in any order. + +Allowing both types of parameters (i.e., a "flexible" shortcode) is useful for complex layouts where you want to set default values that can be easily overridden by users. + +### Access parameters + +All shortcode parameters can be accessed via the `.Get` method. Whether you pass a key (i.e., string) or a number to the `.Get` method depends on whether you are accessing a named or positional parameter, respectively. + +To access a parameter by name, use the `.Get` method followed by the named parameter as a quoted string: + +```go-html-template +{{ .Get "class" }} +``` + +To access a parameter by position, use the `.Get` followed by a numeric position, keeping in mind that positional parameters 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 parameter being set: + +```go-html-template +{{ with .Get "class" }} class="{{ . }}"{{ end }} +``` + +`.Get` can also be used to check if a parameter 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` + - If a closing shortcode is used, the `.Inner` variable will be populated with the content between the opening and closing shortcodes. If a closing shortcode is required, you can check the length of `.Inner` as an indicator of its existence. ++If a closing shortcode is used, the `.Inner` variable will be populated with the content between the opening and closing shortcodes. To check if `.Inner` contains anything other than white space: ++ ++```go-html-template ++{{ if strings.ContainsNonSpace .Inner }} ++ Inner is not empty ++{{ end }} ++``` + +A shortcode with content declared via the `.Inner` variable can also be declared without the content and without the closing tag by using the self-closing syntax: + +```go-html-template +{{}} +``` + +{{% note %}} +Any shortcode that refers to `.Inner` must be closed or self-closed. + +{{% /note %}} + +#### `.Params` + +The `.Params` variable in shortcodes contains the list parameters passed to shortcode for more complicated use cases. You can also access higher-scoped parameters with the following logic: + +`$.Params` +: these are the parameters 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`). + +`$.Page.Site.Params` +: refers to global variables as defined in your [site's configuration file][config]. + +#### `.IsNamedParams` + +The `.IsNamedParams` variable checks whether the shortcode declaration uses named parameters and returns a boolean value. + +For example, you could create an `image` shortcode that can take either a `src` named parameter or the first positional parameter, 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 parameters, you *cannot* declare shortcodes in content with a mix of parameter types. Therefore, a shortcode declared like `{{}}` will return an error. +{{% /note %}} + +You can also use the variable `.Page` to access all the normal [page variables][pagevars]. + +A shortcodes can also be nested. In a nested shortcode, you can access the parent shortcode context with [`.Parent` variable][shortcodesvars]. This can be very useful for inheritance of common shortcode parameters 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 sometimes 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 that can quickly become unsightly. 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" copy=false >}} +
+ +
+{{< /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" copy=false >}} +
+ +
+

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" copy=false >}} +
+ +
+
+ +
+{{< /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" copy=false >}} +
<html>
 +    <body> This HTML </body>
 +</html>
 +
+{{< /code >}} + +### Nested shortcode: image gallery + +Hugo's [`.Parent` shortcode variable][parent] 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 for common shortcode parameters. + +The following example is contrived but demonstrates the concept. Assume you have a `gallery` shortcode that expects one named `class` parameter: + +{{< code file="layouts/shortcodes/gallery.html" >}} +
+ {{ .Inner }} +
+{{< /code >}} + +You also have an `img` shortcode with a single named `src` parameter 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](/functions/errorf) template func and [.Position](/variables/shortcodes/) variable to get useful error messages in shortcodes: + +```bash +{{ with .Get "name" }} +{{ else }} +{{ errorf "missing value for parameter 'name': %s" .Position }} +{{ end }} +``` + +When the above fails, you will see an `ERROR` log similar to the below: + +```bash +ERROR 2018/11/07 10:05:55 missing value for parameter name: "/Users/bep/dev/go/gohugoio/hugo/docs/content/en/variables/shortcodes.md:32:1" +``` + +## More shortcode examples + +More shortcode examples can be found in the [shortcodes directory for spf13.com][spfscs] and the [shortcodes directory for the Hugo docs][docsshortcodes]. + +## 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" >}} +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-text-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 parameters if needed, using the self-closing syntax: + + ```go-text-template +{{}} +``` + +[basic content files]: /content-management/formats/ +[built-in shortcode]: /content-management/shortcodes/ +[config]: /getting-started/configuration/ +[Content Management: Shortcodes]: /content-management/shortcodes/#using-hugo-s-built-in-shortcodes +[source organization]: /getting-started/directory-structure/#directory-structure-explained +[docsshortcodes]: https://github.com/gohugoio/hugo/tree/master/docs/layouts/shortcodes +[figure]: /content-management/shortcodes/#figure +[hugosc]: /content-management/shortcodes/#using-hugo-s-built-in-shortcodes +[lookup order]: /templates/lookup-order/ +[pagevars]: /variables/page/ +[parent]: /variables/shortcodes/ +[shortcodesvars]: /variables/shortcodes/ +[spfscs]: https://github.com/spf13/spf13.com/tree/master/layouts/shortcodes +[vimeoexample]: #single-flexible-example-vimeo +[youtubeshortcode]: /content-management/shortcodes/#youtube diff --cc docs/content/en/templates/single-page-templates.md index 861ced99d,000000000..12e04db96 mode 100644,000000..100644 --- a/docs/content/en/templates/single-page-templates.md +++ b/docs/content/en/templates/single-page-templates.md @@@ -1,85 -1,0 +1,85 @@@ +--- +title: Single page templates +description: The primary view of content in Hugo is the single view. Hugo will render every Markdown file provided with a corresponding single template. +categories: [templates] +keywords: [page, templates] +menu: + docs: + parent: templates + weight: 50 +weight: 50 +aliases: [/layout/content/] +toc: true +--- + +## Single page template lookup order + +See [Template Lookup](/templates/lookup-order/). + +## Example single page templates + +Content pages are of the type `page` and will therefore have all the [page variables][pagevars] and [site variables] available to use in their templates. + +### `posts/single.html` + +This single page template makes use of Hugo [base templates], the [`.Format` function] for dates, the [`.WordCount` page variable][pagevars], and ranges through the single content's specific [taxonomies][pagetaxonomy]. [`with`] is also used to check whether the taxonomies are set in the front matter. + +{{< code file="layouts/posts/single.html" >}} +{{ define "main" }} +
+

{{ .Title }}

+
+
+ {{ .Content }} +
+
+
+ +{{ end }} +{{< /code >}} + +To easily generate new instances of a content type (e.g., new `.md` files in a section like `project/`) with preconfigured front matter, use [content archetypes][archetypes]. + +[archetypes]: /content-management/archetypes/ +[base templates]: /templates/base/ +[content type]: /content-management/types/ +[directory structure]: /getting-started/directory-structure/ +[dry]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself +[`.format` function]: /functions/format/ +[front matter]: /content-management/front-matter/ +[pagetaxonomy]: /templates/taxonomy-templates/#list-terms-assigned-to-a-page +[pagevars]: /variables/page/ +[partials]: /templates/partials/ +[section]: /content-management/sections/ +[site variables]: /variables/site/ +[spf13]: https://spf13.com/ +[`with`]: /functions/with/ diff --cc docs/content/en/tools/editors.md index 92720ab42,000000000..085febced mode 100644,000000..100644 --- a/docs/content/en/tools/editors.md +++ b/docs/content/en/tools/editors.md @@@ -1,40 -1,0 +1,38 @@@ +--- +title: Editor plugins for Hugo +linkTitle: Editor plugins +description: The Hugo community uses a wide range of preferred tools and has developed plug-ins for some of the most popular text editors to help automate parts of your workflow. +categories: [developer tools] +keywords: [editor, plug-ins] +menu: + docs: + parent: developer-tools + weight: 20 +weight: 20 +--- + - The Hugo community uses a wide range of preferred tools and has developed plug-ins for some of the most popular text editors to help automate parts of your workflow. - +## Sublime Text + +* [Hugofy](https://github.com/akmittal/Hugofy). Hugofy is a plugin for Sublime Text 3 to make life easier to use Hugo static site generator. +* [Hugo Snippets](https://packagecontrol.io/packages/Hugo%20Snippets). Hugo Snippets is a useful plugin for adding automatic snippets to Sublime Text 3. + +## Visual Studio Code + +* [Hugofy](https://marketplace.visualstudio.com/items?itemName=akmittal.hugofy). Hugofy is a plugin for Visual Studio Code to "make life easier" when developing with Hugo. The source code can be found [here](https://github.com/akmittal/hugofy-vscode). +* [Hugo Helper](https://marketplace.visualstudio.com/items?itemName=rusnasonov.vscode-hugo). Hugo Helper is a plugin for Visual Studio Code that has some useful commands for Hugo. The source code can be found [here](https://github.com/rusnasonov/vscode-hugo). +* [Hugo Language and Syntax Support](https://marketplace.visualstudio.com/items?itemName=budparr.language-hugo-vscode). Hugo Language and Syntax Support is a Visual Studio Code plugin for Hugo syntax highlighting and snippets. The source code can be found [here](https://github.com/budparr/language-hugo-vscode). +* [Hugo Themer](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-hugo-themer). Hugo Themer is an extension to help you while developing themes. It allows you to easily navigate through your theme files. +* [Front Matter](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter). Once you go for a static site, you need to think about how you are going to manage your articles. Front matter is a tool that helps you maintain the metadata/front matter of your articles like: creation date, modified date, slug, tile, SEO check, and many more... - * [Syntax Highlighting for Hugo Shortcodes](https://marketplace.visualstudio.com/items?itemName=kaellarkin.hugo-shortcode-syntax). This extension add some syntax highlighting for Shortcodes, making visual identification of individual pieces easier. ++* [Syntax Highlighting for Hugo Shortcodes](https://marketplace.visualstudio.com/items?itemName=kaellarkin.hugo-shortcode-syntax). This extension adds some syntax highlighting for Shortcodes, making visual identification of individual pieces easier. + +## Emacs + +* [emacs-easy-hugo](https://github.com/masasam/emacs-easy-hugo). Emacs major mode for managing hugo blogs. Note that Hugo also supports [Org-mode][formats]. +* [ox-hugo.el](https://ox-hugo.scripter.co). Native Org-mode exporter that exports to Blackfriday Markdown with Hugo front-matter. `ox-hugo` supports two common Org blogging flows --- exporting multiple Org subtrees in a single file to multiple Hugo posts, and exporting a single Org file to a single Hugo post. It also leverages the Org tag and property inheritance features. See [*Why ox-hugo?*](https://ox-hugo.scripter.co/doc/why-ox-hugo/) for more. + +## Vim + - * [Vim Hugo Helper](https://github.com/robertbasic/vim-hugo-helper). A small Vim plugin to help me with writing posts with Hugo. ++* [Vim Hugo Helper](https://github.com/robertbasic/vim-hugo-helper). A small Vim plugin that facilitates authoring pages and blog posts with Hugo. +* [vim-hugo](https://github.com/phelipetls/vim-hugo). A Vim plugin with syntax highlighting for templates and a few other features. + +[formats]: /content-management/formats/ diff --cc docs/content/en/variables/page.md index fc6e2f567,000000000..51b0b2fc1 mode 100644,000000..100644 --- a/docs/content/en/variables/page.md +++ b/docs/content/en/variables/page.md @@@ -1,325 -1,0 +1,320 @@@ +--- +title: Page variables +description: Page-level variables are defined in a content file's front matter, derived from the content's file location, or extracted from the content body itself. +categories: [variables and parameters] +keywords: [pages] +menu: + docs: + parent: variables + weight: 20 +weight: 20 +toc: true +--- + +The following is a list of page-level variables. Many of these will be defined in the front matter, derived from file location, or extracted from the content itself. + +## Page variables + +.AlternativeOutputFormats - : contains all alternative formats for a given page; this variable is especially useful `link rel` list in your site's ``. (See [Output Formats](/templates/output-formats/).) ++: Contains all alternative formats for a given page; this variable is especially useful `link rel` list in your site's ``. (See [Output Formats](/templates/output-formats/).) + +.Aliases - : aliases of this page ++: Aliases of this page + +.Ancestors - : get the ancestors of each page, simplify [breadcrumb navigation](/content-management/sections#example-breadcrumb-navigation) implementation complexity ++: Get the ancestors of each page, simplify [breadcrumb navigation](/content-management/sections#example-breadcrumb-navigation) implementation complexity + +.BundleType - : the [bundle] type: `leaf`, `branch`, or an empty string if the page is not a bundle. ++: The [bundle] type: `leaf`, `branch`, or an empty string if the page is not a bundle. + +.Content - : the content itself, defined below the front matter. ++: The content itself, defined below the front matter. + +.Data - : the data specific to this type of page. ++: The data specific to this type of page. + +.Date - : the date associated with the page; `.Date` pulls from the `date` field in a content's front matter. See also `.ExpiryDate`, `.PublishDate`, and `.Lastmod`. ++: The date associated with the page. By default, this is the front matter `date` value. See [configuring dates] for a description of fallback values and precedence. See also `.ExpiryDate`, `.Lastmod`, and `.PublishDate`. + +.Description - : the description for the page. ++: The description for the page. + +.Draft - : a boolean, `true` if the content is marked as a draft in the front matter. ++: A boolean, `true` if the content is marked as a draft in the front matter. + +.ExpiryDate - : the date on which the content is scheduled to expire; `.ExpiryDate` pulls from the `expirydate` field in a content's front matter. See also `.PublishDate`, `.Date`, and `.Lastmod`. ++: The date on which the content is scheduled to expire. By default, this is the front matter `expiryDate` value. See [configuring dates] for a description of fallback values and precedence. See also `.Date`, `.Lastmod`, and `.PublishDate`. + +.File - : filesystem-related data for this content file. See also [File Variables]. ++: Filesystem-related data for this content file. See also [File Variables]. + +.Fragments +: Fragments returns the fragments for this page. See [Page Fragments](#page-fragments). + +.FuzzyWordCount - : the approximate number of words in the content. ++: The approximate number of words in the content. + +.IsHome +: `true` in the context of the [homepage](/templates/homepage/). + +.IsNode - : always `false` for regular content pages. ++: Always `false` for regular content pages. + +.IsPage - : always `true` for regular content pages. ++: Always `true` for regular content pages. + +.IsSection +: `true` if [`.Kind`](/templates/section-templates/#page-kinds) is `section`. + +.IsTranslated +: `true` if there are translations to display. + +.Keywords - : the meta keywords for the content. ++: The meta keywords for the content. + +.Kind - : the page's *kind*. Possible return values are `page`, `home`, `section`, `taxonomy`, or `term`. Note that there are also `RSS`, `sitemap`, `robotsTXT`, and `404` kinds, but these are only available during the rendering of each of these respective page's kind and therefore *not* available in any of the `Pages` collections. ++: The page's *kind*. Possible return values are `page`, `home`, `section`, `taxonomy`, or `term`. Note that there are also `RSS`, `sitemap`, `robotsTXT`, and `404` kinds, but these are only available during the rendering of each of these respective page's kind and therefore *not* available in any of the `Pages` collections. + +.Language - : a language object that points to the language's definition in the site configuration. `.Language.Lang` gives you the language code. ++: A language object that points to the language's definition in the site configuration. `.Language.Lang` gives you the language code. + +.Lastmod - : the date the content was last modified. `.Lastmod` pulls from the `lastmod` field in a content's front matter. - - - If `lastmod` is not set, and `.GitInfo` feature is disabled, the front matter `date` field will be used. - - If `lastmod` is not set, and `.GitInfo` feature is enabled, `.GitInfo.AuthorDate` will be used instead. - - See also `.ExpiryDate`, `.Date`, `.PublishDate`, and [`.GitInfo`][gitinfo]. ++: The date on which the content was last modified. By default, if `enableGitInfo` is `true` in your site configuration, this is the Git author date, otherwise the front matter `lastmod` value. See [configuring dates] for a description of fallback values and precedence. See also `.Date`,`ExpiryDate`, `.PublishDate`, and [`.GitInfo`][gitinfo]. + +.LinkTitle - : access when creating links to the content. If set, Hugo will use the `linktitle` from the front matter before `title`. ++: Access when creating links to the content. If set, Hugo will use the `linktitle` from the front matter before `title`. + +.Next +: Points up to the next [regular page](/variables/site/#site-pages) (sorted by Hugo's [default sort](/templates/lists#default-weight--date--linktitle--filepath)). Example: `{{ with .Next }}{{ .Permalink }}{{ end }}`. Calling `.Next` from the first page returns `nil`. + +.NextInSection +: Points up to the next [regular page](/variables/site/#site-pages) below the same top level section (e.g. in `/blog`)). Pages are sorted by Hugo's [default sort](/templates/lists#default-weight--date--linktitle--filepath). Example: `{{ with .NextInSection }}{{ .Permalink }}{{ end }}`. Calling `.NextInSection` from the first page returns `nil`. + +.OutputFormats - : contains all formats, including the current format, for a given page. Can be combined the with [`.Get` function](/functions/get/) to grab a specific format. (See [Output Formats](/templates/output-formats/).) ++: Contains all formats, including the current format, for a given page. Can be combined the with [`.Get` function](/functions/get/) to grab a specific format. (See [Output Formats](/templates/output-formats/).) + +.Pages - : a collection of associated pages. This value will be `nil` within - the context of regular content pages. See [`.Pages`](#pages). ++: A collection of associated pages. This value will be `nil` within the context of regular content pages. See [`.Pages`](#pages). + +.Permalink - : the Permanent link for this page; see [Permalinks](/content-management/urls/) ++: The Permanent link for this page; see [Permalinks](/content-management/urls/) + +.Plain - : the Page content stripped of HTML tags and presented as a string. You may need to pipe the result through the [`htmlUnescape`](/functions/htmlunescape/) function when rendering this value with the HTML [output format](/templates/output-formats#output-format-definitions). ++: The Page content stripped of HTML tags and presented as a string. You may need to pipe the result through the [`htmlUnescape`](/functions/htmlunescape/) function when rendering this value with the HTML [output format](/templates/output-formats#output-format-definitions). + +.PlainWords - : the slice of strings that results from splitting .Plain into words, as defined in Go's [strings.Fields](https://pkg.go.dev/strings#Fields). ++: The slice of strings that results from splitting .Plain into words, as defined in Go's [strings.Fields](https://pkg.go.dev/strings#Fields). + +.Prev +: Points down to the previous [regular page](/variables/site/#site-pages) (sorted by Hugo's [default sort](/templates/lists#default-weight--date--linktitle--filepath)). Example: `{{ if .Prev }}{{ .Prev.Permalink }}{{ end }}`. Calling `.Prev` from the last page returns `nil`. + +.PrevInSection +: Points down to the previous [regular page](/variables/site/#site-pages) below the same top level section (e.g. `/blog`). Pages are sorted by Hugo's [default sort](/templates/lists#default-weight--date--linktitle--filepath). Example: `{{ if .PrevInSection }}{{ .PrevInSection.Permalink }}{{ end }}`. Calling `.PrevInSection` from the last page returns `nil`. + +.PublishDate - : the date on which the content was or will be published; `.Publishdate` pulls from the `publishdate` field in a content's front matter. See also `.ExpiryDate`, `.Date`, and `.Lastmod`. ++: The date on which the content was or will be published. By default, this is the front matter `publishDate` value. See [configuring dates] for a description of fallback values and precedence. See also `.Date`, `.ExpiryDate`, and `.Lastmod`. + +.RawContent - : raw markdown content without the front matter. Useful with [remarkjs.com]( ++: Raw markdown content without the front matter. Useful with [remarkjs.com]( +https://remarkjs.com) + +.ReadingTime - : the estimated time, in minutes, it takes to read the content. ++: The estimated time, in minutes, it takes to read the content. + +.Resources - : resources such as images and CSS that are associated with this page ++: Resources such as images and CSS that are associated with this page + +.Ref - : returns the permalink for a given reference (e.g., `.Ref "sample.md"`). `.Ref` does *not* handle in-page fragments correctly. See [Cross References](/content-management/cross-references/). ++: Returns the permalink for a given reference (e.g., `.Ref "sample.md"`). `.Ref` does *not* handle in-page fragments correctly. See [Cross References](/content-management/cross-references/). + +.RelPermalink - : the relative permanent link for this page. ++: The relative permanent link for this page. + +.RelRef - : returns the relative permalink for a given reference (e.g., `RelRef ++: Returns the relative permalink for a given reference (e.g., `RelRef +"sample.md"`). `.RelRef` does *not* handle in-page fragments correctly. See [Cross References](/content-management/cross-references/). + +.Site - : see [Site Variables](/variables/site/). ++: See [Site Variables](/variables/site/). + +.Sites - : returns all sites (languages). A typical use case would be to link back to the main language: `...`. ++: Returns all sites (languages). A typical use case would be to link back to the main language: `...`. + +.Sites.First - : returns the site for the first language. If this is not a multilingual setup, it will return itself. ++: Returns the site for the first language. If this is not a multilingual setup, it will return itself. + +.Summary - : a generated summary of the content for easily showing a snippet in a summary view. The breakpoint can be set manually by inserting <!--more--> at the appropriate place in the content page, or the summary can be written independent of the page text. See [Content Summaries](/content-management/summaries/) for more details. ++: A generated summary of the content for easily showing a snippet in a summary view. The breakpoint can be set manually by inserting <!--more--> at the appropriate place in the content page, or the summary can be written independent of the page text. See [Content Summaries](/content-management/summaries/) for more details. + +.TableOfContents - : the rendered [table of contents](/content-management/toc/) for the page. ++: The rendered [table of contents](/content-management/toc/) for the page. + +.Title - : the title for this page. ++: The title for this page. + +.Translations - : a list of translated versions of the current page. See [Multilingual Mode](/content-management/multilingual/) for more information. ++: A list of translated versions of the current page. See [Multilingual Mode](/content-management/multilingual/) for more information. + +.TranslationKey - : the key used to map language translations of the current page. See [Multilingual Mode](/content-management/multilingual/) for more information. ++: The key used to map language translations of the current page. See [Multilingual Mode](/content-management/multilingual/) for more information. + +.Truncated - : a boolean, `true` if the `.Summary` is truncated. Useful for showing a "Read more..." link only when necessary. See [Summaries](/content-management/summaries/) for more information. ++: A boolean, `true` if the `.Summary` is truncated. Useful for showing a "Read more..." link only when necessary. See [Summaries](/content-management/summaries/) for more information. + +.Type - : the [content type](/content-management/types/) of the content (e.g., `posts`). ++: The [content type](/content-management/types/) of the content (e.g., `posts`). + +.Weight - : assigned weight (in the front matter) to this content, used in sorting. ++: Assigned weight (in the front matter) to this content, used in sorting. + +.WordCount - : the number of words in the content. ++: The number of words in the content. + +## Writable page-scoped variables + +[.Scratch][scratch] - : returns a Scratch to store and manipulate data. In contrast to the [`.Store`][store] method, this scratch is reset on server rebuilds. ++: Returns a Scratch to store and manipulate data. In contrast to the [`.Store`][store] method, this scratch is reset on server rebuilds. + +[.Store][store] - : returns a Scratch to store and manipulate data. In contrast to the [`.Scratch`][scratch] method, this scratch is not reset on server rebuilds. ++: Returns a Scratch to store and manipulate data. In contrast to the [`.Scratch`][scratch] method, this scratch is not reset on server rebuilds. + +## Section variables and methods + +Also see [Sections](/content-management/sections/). + +{{< readfile file="/content/en/readfiles/sectionvars.md" markdown="true" >}} + +## The `.Pages` variable {#pages} + +`.Pages` is an alias to `.Data.Pages`. It is conventional to use the +aliased form `.Pages`. + +### `.Pages` compared to `.Site.Pages` + +{{< getcontent path="readfiles/pages-vs-site-pages.md" >}} + +## Page fragments + +{{< new-in "0.111.0" >}} + +The `.Fragments` method returns a list of fragments for the current page. + +.Headings +: A recursive list of headings for the current page. Can be used to generate a table of contents. + +{{< todo >}}add .Headings toc example{{< /todo >}} + +.Identifiers +: A sorted list of identifiers for the current page. Can be used to check if a page contains a specific identifier or if a page contains duplicate identifiers: + +```go-html-template +{{ if .Fragments.Identifiers.Contains "my-identifier" }} +

Page contains identifier "my-identifier"

+{{ end }} + +{{ if gt (.Fragments.Identifiers.Count "my-identifier") 1 }} +

Page contains duplicate "my-identifier" fragments

+{{ end }} +``` + +.HeadingsMap +: Holds a map of headings for the current page. Can be used to start the table of contents from a specific heading. + +Also see the [Go Doc](https://pkg.go.dev/github.com/gohugoio/hugo@v0.111.0/markup/tableofcontents#Fragments) for the return type. + +### Fragments in hooks and shortcodes + +`.Fragments` are safe to call from render hooks, even on the page you're on (`.Page.Fragments`). For shortcodes we recommend that all `.Fragments` usage is nested inside the `{{}}` shortcode delimiter (`{{%/**/%}}` takes part in the ToC creation so it's easy to end up in a situation where you bite yourself in the tail). + + +## The global page function + +{{< new-in "0.111.1" >}} + +Hugo almost always passes a `Page` as the data context into the top level template (e.g. `single.html`) (the one exception is the multihost sitemap template). This means that you can access the current page with the `.` variable in the template. + +But when you're deeply nested inside `.Render`, partial etc., accessing that `Page` object isn't always practical or possible. + +For this reason, Hugo provides a global `page` function that you can use to access the current page from anywhere in any template. + +```go-html-template +{{ page.Title }} +``` + - There are one caveat with this, and this isn't new, but it's worth mentioning here: There are situations in Hugo where you may see a cached value, e.g. when using `partialCached` or in a shortcode. ++There are one caveat with this, and this isn't new, but it's worth mentioning here: There are situations in Hugo where you may see a cached value, e.g. when using `partialCached` or in a shortcode. + +## Page-level params + +Any other value defined in the front matter in a content file, including taxonomies, will be made available as part of the `.Params` variable. + +{{< code-toggle file="content/example.md" fm=true copy=false >}} +title: Example +categories: [one] +tags: [two,three,four] +{{< /code-toggle >}} + +With the above front matter, the `tags` and `categories` taxonomies are accessible via the following: + +* `.Params.tags` +* `.Params.categories` + +The `.Params` variable is particularly useful for the introduction of user-defined front matter fields in content files. For example, a Hugo website on book reviews could have the following front matter: + +{{< code-toggle file="content/example.md" fm=true copy=false >}} +title: Example +affiliatelink: "http://www.my-book-link.here" +recommendedby: "My Mother" +{{< /code-toggle >}} + +These fields would then be accessible to via `.Params.affiliatelink` and `.Params.recommendedby`. + +```go-html-template +

Buy this book

+

It was recommended by {{ .Params.recommendedby }}.

+``` + +This template would render as follows: + +```html +

Buy this book

+

It was recommended by my Mother.

+``` + +{{% note %}} +See [Archetypes](/content-management/archetypes/) for consistency of `Params` across pieces of content. +{{% /note %}} + +### The `.Param` method + +In Hugo, you can declare parameters in individual pages and globally for your entire website. A common use case is to have a general value for the site parameter and a more specific value for some of the pages (i.e., a header image): + +```go-html-template +{{ $.Param "header_image" }} +``` + +The `.Param` method provides a way to resolve a single value according to it's definition in a page parameter (i.e. in the content's front matter) or a site parameter (i.e., in your site configuration). + +### Access nested fields in front matter + +When front matter contains nested fields like the following: + +{{< code-toggle file="content/example.md" fm=true copy=false >}} +title: Example +author: + given_name: John + family_name: Feminella + display_name: John Feminella +{{< /code-toggle >}} + +`.Param` can access these fields by concatenating the field names together with a dot: + +```go-html-template +{{ $.Param "author.display_name" }} +``` + ++[configuring dates]: /getting-started/configuration/#configure-dates +[gitinfo]: /variables/git/ +[File Variables]: /variables/files/ +[bundle]: /content-management/page-bundles +[scratch]: /functions/scratch +[store]: /functions/store diff --cc docs/netlify.toml index 3df9a72c9,000000000..366e4f813 mode 100644,000000..100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@@ -1,35 -1,0 +1,35 @@@ +[build] +publish = "public" +command = "hugo --gc --minify" + +[context.production.environment] - HUGO_VERSION = "0.115.4" ++HUGO_VERSION = "0.116.1" +HUGO_ENV = "production" +HUGO_ENABLEGITINFO = "true" + +[context.split1] +command = "hugo --gc --minify --enableGitInfo" + +[context.split1.environment] - HUGO_VERSION = "0.115.4" ++HUGO_VERSION = "0.116.1" +HUGO_ENV = "production" + +[context.deploy-preview] +command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL" + +[context.deploy-preview.environment] - HUGO_VERSION = "0.115.4" ++HUGO_VERSION = "0.116.1" + +[context.branch-deploy] +command = "hugo --gc --minify -b $DEPLOY_PRIME_URL" + +[context.branch-deploy.environment] - HUGO_VERSION = "0.115.4" ++HUGO_VERSION = "0.116.1" + +[context.next.environment] +HUGO_ENABLEGITINFO = "true" + +[[redirects]] +from = "/npmjs/*" +to = "/npmjs/" +status = 200