From: Bjørn Erik Pedersen Date: Thu, 24 Apr 2025 08:23:16 +0000 (+0200) Subject: Merge commit 'b3d87dd0fd746f07f9afa6e6a2969aea41da6a38' X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=61a286595e9a333fef95db1e9a086ef9367b3d87;p=brevno-suite%2Fhugo Merge commit 'b3d87dd0fd746f07f9afa6e6a2969aea41da6a38' --- 61a286595e9a333fef95db1e9a086ef9367b3d87 diff --cc docs/content/en/configuration/introduction.md index 121a483c4,000000000..8f8ad4c1e mode 100644,000000..100644 --- a/docs/content/en/configuration/introduction.md +++ b/docs/content/en/configuration/introduction.md @@@ -1,284 -1,0 +1,284 @@@ +--- +title: Introduction +description: Configure your site using files, directories, and environment variables. +categories: [] +keywords: [] +weight: 10 +--- + +## Sensible defaults + +Hugo offers many configuration options, but its defaults are often sufficient. A new site requires only these settings: + +{{< code-toggle file=hugo >}} +baseURL = 'https://example.org/' +languageCode = 'en-us' +title = 'My New Hugo Site' +{{< /code-toggle >}} + +Only define settings that deviate from the defaults. A smaller configuration file is easier to read, understand, and debug. Keep your configuration concise. + +> [!note] +> The best configuration file is a short configuration file. + +## Configuration file + +Create a site configuration file in the root of your project directory, naming it `hugo.toml`, `hugo.yaml`, or `hugo.json`, with that order of precedence. + +```text +my-project/ +└── hugo.toml +``` + +> [!note] +> For versions v0.109.0 and earlier, the site configuration file was named `config`. While you can still use this name, it's recommended to switch to the newer naming convention, `hugo`. + +A simple example: + +{{< code-toggle file=hugo >}} +baseURL = 'https://example.org/' +languageCode = 'en-us' +title = 'ABC Widgets, Inc.' +[params] +subtitle = 'The Best Widgets on Earth' +[params.contact] +email = 'info@example.org' +phone = '+1 202-555-1212' +{{< /code-toggle >}} + +To use a different configuration file when building your site, use the `--config` flag: + +```sh +hugo --config other.toml +``` + +Combine two or more configuration files, with left-to-right precedence: + +```sh +hugo --config a.toml,b.yaml,c.json +``` + +> [!note] +> See the specifications for each file format: [TOML], [YAML], and [JSON]. + +## Configuration directory + +Instead of a single site configuration file, split your configuration by [environment](g), root configuration key, and language. For example: + +```text +my-project/ +└── config/ + ├── _default/ + │ ├── hugo.toml + │ ├── menus.en.toml + │ ├── menus.de.toml + │ └── params.toml + └── production/ + └── params.toml +``` + +The root configuration keys are {{< root-configuration-keys >}}. + +### Omit the root key + +When splitting the configuration by root key, omit the root key in the component file. For example, these are equivalent: + +{{< code-toggle file=config/_default/hugo >}} +[params] +foo = 'bar' +{{< /code-toggle >}} + +{{< code-toggle file=config/_default/params >}} +foo = 'bar' +{{< /code-toggle >}} + +### Recursive parsing + +Hugo parses the `config` directory recursively, allowing you to organize the files into subdirectories. For example: + +```text +my-project/ +└── config/ + └── _default/ + ├── navigation/ + │ ├── menus.de.toml + │ └── menus.en.toml + └── hugo.toml +``` + +### Example + +```text +my-project/ +└── config/ + ├── _default/ + │ ├── hugo.toml + │ ├── menus.en.toml + │ ├── menus.de.toml + │ └── params.toml + ├── production/ + │ ├── hugo.toml + │ └── params.toml + └── staging/ + ├── hugo.toml + └── params.toml +``` + +Considering the structure above, when running `hugo --environment staging`, Hugo will use every setting from `config/_default` and merge `staging`'s on top of those. + +Let's take an example to understand this better. Let's say you are using Google Analytics for your website. This requires you to specify a [Google tag ID] in your site configuration: + +{{< code-toggle file=hugo >}} +[services.googleAnalytics] +ID = 'G-XXXXXXXXX' +{{< /code-toggle >}} + +Now consider the following scenario: + +1. You don't want to load the analytics code when running `hugo server`. +1. You want to use different Google tag IDs for your production and staging environments. For example: + - `G-PPPPPPPPP` for production + - `G-SSSSSSSSS` for staging + +To satisfy these requirements, configure your site as follows: + +1. `config/_default/hugo.toml` + - Exclude the `services.googleAnalytics` section. This will prevent loading of the analytics code when you run `hugo server`. + - By default, Hugo sets its `environment` to `development` when running `hugo server`. In the absence of a `config/development` directory, Hugo uses the `config/_default` directory. +1. `config/production/hugo.toml` + - Include this section only: + + {{< code-toggle file=hugo >}} + [services.googleAnalytics] + ID = 'G-PPPPPPPPP' + {{< /code-toggle >}} + + - You do not need to include other parameters in this file. Include only those parameters that are specific to your production environment. Hugo will merge these parameters with the default configuration. + - By default, Hugo sets its `environment` to `production` when running `hugo`. The analytics code will use the `G-PPPPPPPPP` tag ID. + +1. `config/staging/hugo.toml` + + - Include this section only: + + {{< code-toggle file=hugo >}} + [services.googleAnalytics] + ID = 'G-SSSSSSSSS' + {{< /code-toggle >}} + + - You do not need to include other parameters in this file. Include only those parameters that are specific to your staging environment. Hugo will merge these parameters with the default configuration. + - To build your staging site, run `hugo --environment staging`. The analytics code will use the `G-SSSSSSSSS` tag ID. + +## Merge configuration settings + +Hugo merges configuration settings from themes and modules, prioritizing the project's own settings. Given this simplified project structure with two themes: + +```text +project/ +├── themes/ +│ ├── theme-a/ +│ │ └── hugo.toml +│ └── theme-b/ +│ └── hugo.toml +└── hugo.toml +``` + +and this project-level configuration: + +{{< code-toggle file=hugo >}} +baseURL = 'https://example.org/' +languageCode = 'en-us' +title = 'My New Hugo Site' +theme = ['theme-a','theme-b'] +{{< /code-toggle >}} + +Hugo merges settings in this order: + +1. Project configuration (`hugo.toml` in the project root) +1. `theme-a` configuration +1. `theme-b` configuration + +The `_merge` setting within each top-level configuration key controls _which_ settings are merged and _how_ they are merged. + +The value for `_merge` can be one of: + +none +: No merge. + +shallow +: Only add values for new keys. + +deep +: Add values for new keys, merge existing. + +Note that you don't need to be so verbose as in the default setup below; a `_merge` value higher up will be inherited if not set. + +{{< code-toggle file=hugo dataKey="config_helpers.mergeStrategy" skipHeader=true />}} + +## Environment variables + +You can also configure settings using operating system environment variables: + +```sh +export HUGO_BASEURL=https://example.org/ +export HUGO_ENABLEGITINFO=true +export HUGO_ENVIRONMENT=staging +hugo +``` + +The above sets the [`baseURL`], [`enableGitInfo`], and [`environment`] configuration options and then builds your site. + +> [!note] +> An environment variable takes precedence over the values set in the configuration file. This means that if you set a configuration value with both an environment variable and in the configuration file, the value in the environment variable will be used. + +Environment variables simplify configuration for [CI/CD](g) deployments like GitHub Pages, GitLab Pages, and Netlify by allowing you to set values directly within their respective configuration and workflow files. + +> [!note] +> Environment variable names must be prefixed with `HUGO_`. +> +> To set custom site parameters, prefix the name with `HUGO_PARAMS_`. + +For snake_case variable names, the standard `HUGO_` prefix won't work. Hugo infers the delimiter from the first character following `HUGO`. This allows for variations like `HUGOxPARAMSxAPI_KEY=abcdefgh` using any [permitted delimiter]. + +In addition to configuring standard settings, environment variables may be used to override default values for certain internal settings: + +DART_SASS_BINARY +: (`string`) The absolute path to the Dart Sass executable. By default, Hugo searches for the executable in each of the paths in the `PATH` environment variable. + +HUGO_FILE_LOG_FORMAT +: (`string`) A format string for the file path, line number, and column number displayed when reporting errors, or when calling the `Position` method from a shortcode or Markdown render hook. Valid tokens are `:file`, `:line`, and `:col`. Default is `:file::line::col`. + +HUGO_MEMORYLIMIT +: {{< new-in 0.123.0 />}} - : (`int`) The maximum amount of system memory, in gigabytes, that Hugo can use while rendering your site. Default is 25% of total system memory. Note that The `HUGO_MEMORYLIMIT` is a “best effort” setting. Don't expect Hugo to build a million pages with only 1 GB memory. You can get more information about how this behaves during the build by building with `hugo --logLevel info` and look for the `dynacache` label. ++: (`int`) The maximum amount of system memory, in gigabytes, that Hugo can use while rendering your site. Default is 25% of total system memory. Note that `HUGO_MEMORYLIMIT` is a "best effort" setting. Don't expect Hugo to build a million pages with only 1 GB of memory. You can get more information about how this behaves during the build by building with `hugo --logLevel info` and look for the `dynacache` label. + +HUGO_NUMWORKERMULTIPLIER +: (`int`) The number of workers used in parallel processing. Default is the number of logical CPUs. + +## Current configuration + +Display the complete site configuration with: + +```sh +hugo config +``` + +Display a specific configuration setting with: + +```sh +hugo config | grep [key] +``` + +Display the configured file mounts with: + +```sh +hugo config mounts +``` + +[`baseURL`]: /configuration/all#baseurl +[`enableGitInfo`]: /configuration/all#enablegitinfo +[`environment`]: /configuration/all#environment +[Google tag ID]: https://support.google.com/tagmanager/answer/12326985?hl=en +[JSON]: https://datatracker.ietf.org/doc/html/rfc7159 +[permitted delimiter]: https://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap08.html +[TOML]: https://toml.io/en/latest +[YAML]: https://yaml.org/spec/ diff --cc docs/content/en/content-management/menus.md index ab1bcbfa1,000000000..6d01173dc mode 100644,000000..100644 --- a/docs/content/en/content-management/menus.md +++ b/docs/content/en/content-management/menus.md @@@ -1,97 -1,0 +1,97 @@@ +--- +title: Menus +description: Create menus by defining entries, localizing each entry, and rendering the resulting data structure. +categories: [] +keywords: [] +aliases: [/extras/menus/] +--- + +## Overview + +To create a menu for your site: + +1. Define the menu entries - 1. [Localize] each entry ++1. [Localize](multilingual/#menus) each entry +1. Render the menu with a [template] + +Create multiple menus, either flat or nested. For example, create a main menu for the header, and a separate menu for the footer. + +There are three ways to define menu entries: + +1. Automatically +1. In front matter +1. In site configuration + +> [!note] +> Although you can use these methods in combination when defining a menu, the menu will be easier to conceptualize and maintain if you use one method throughout the site. + +## Define automatically + +To automatically define a menu entry for each top-level [section](g) of your site, enable the section pages menu in your site configuration. + +{{< code-toggle file=hugo >}} +sectionPagesMenu = "main" +{{< /code-toggle >}} + +This creates a menu structure that you can access with `site.Menus.main` in your templates. See [menu templates] for details. + +## Define in front matter + +To add a page to the "main" menu: + +{{< code-toggle file=content/about.md fm=true >}} +title = 'About' +menus = 'main' +{{< /code-toggle >}} + +Access the entry with `site.Menus.main` in your templates. See [menu templates] for details. + +To add a page to the "main" and "footer" menus: + +{{< code-toggle file=content/contact.md fm=true >}} +title = 'Contact' +menus = ['main','footer'] +{{< /code-toggle >}} + +Access the entry with `site.Menus.main` and `site.Menus.footer` in your templates. See [menu templates] for details. + +> [!note] +> The configuration key in the examples above is `menus`. The `menu` (singular) configuration key is an alias for `menus`. + +### Properties + +Use these properties when defining menu entries in front matter: + +{{% include "/_common/menu-entry-properties.md" %}} + +### Example + +This front matter menu entry demonstrates some of the available properties: + +{{< code-toggle file=content/products/software.md fm=true >}} +title = 'Software' +[menus.main] +parent = 'Products' +weight = 20 +pre = '' +[menus.main.params] +class = 'center' +{{< /code-toggle >}} + +Access the entry with `site.Menus.main` in your templates. See [menu templates] for details. + +## Define in site configuration + +See [configure menus](/configuration/menus/). + +## Localize + +Hugo provides two methods to localize your menu entries. See [multilingual]. + +## Render + +See [menu templates]. + +[menu templates]: /templates/menu/ +[multilingual]: /content-management/multilingual/#menus +[template]: /templates/menu/ diff --cc docs/content/en/contribute/documentation.md index 1d185d21d,000000000..68129912a mode 100644,000000..100644 --- a/docs/content/en/contribute/documentation.md +++ b/docs/content/en/contribute/documentation.md @@@ -1,530 -1,0 +1,530 @@@ +--- +title: Documentation +description: Help us to improve the documentation by identifying issues and suggesting changes. +categories: [] +keywords: [] +aliases: [/contribute/docs/] +--- + +## Introduction + +We welcome corrections and improvements to the documentation. The documentation lives in a separate repository from the main project. To contribute: + +- For corrections and improvements to existing documentation, submit issues and pull requests to the [documentation repository]. +- For documentation of new features, include the documentation changes in your pull request to the [project repository]. + +## Guidelines + +### Style + +Follow Google's [developer documentation style guide]. + +### Markdown + +Adhere to these Markdown conventions: + +- Use [ATX] headings (levels 2-4), not [setext] headings. +- Use [fenced code blocks], not [indented code blocks]. +- Use hyphens, not asterisks, for unordered [list items]. +- Use [callouts](#callouts) instead of bold text for emphasis. +- Do not mix [raw HTML] within Markdown. +- Do not use bold text in place of a heading or description term (`dt`). +- Remove consecutive blank lines. +- Remove trailing spaces. + +### Glossary + +[Glossary] terms are defined on individual pages, providing a central repository for definitions, though these pages are not directly linked from the site. + +Definitions must be complete sentences, with the first sentence defining the term. Italicize the first occurrence of the term and any referenced glossary terms for consistency. + +Link to glossary terms using this syntax: `[term](g)` + +Term lookups are case-insensitive, ignore formatting, and support singular and plural forms. For example, all of these variations will link to the same glossary term: + +```text +[global resource](g) +[Global Resource](g) +[Global Resources](g) +[`Global Resources`](g) +``` + +Use the [glossary-term shortcode](#glossary-term) to insert a term definition: + +```text +{{%/* glossary-term "global resource" */%}} +``` + +### Terminology + +Link to the [glossary] as needed and use terms consistently. Pay particular attention to: + +- "front matter" (two words, except when referring to the configuration key) +- "home page" (two words) +- "website" (one word) +- "standalone" (one word, no hyphen) +- "map" (instead of "dictionary") +- "flag" (instead of "option" for command-line flags) +- "client side" (noun), "client-side" (adjective) +- "server side" (noun), "server-side" (adjective) +- "Markdown" (capitalized) +- "open-source" (hyphenated adjective) + +### Titles and headings + +- Use sentence-style capitalization. +- Avoid formatted strings. +- Keep them concise. + +### Page descriptions + +When writing the page `description` use imperative present tense when possible. For example: + +{{< code-toggle file=content/en/functions/data/_index.md" fm=true >}} +title: Data functions +linkTitle: data +description: Use these functions to read local or remote data files. +{{< /code-toggle >}} + +### Writing style + +Use active voice and present tense wherever possible. + +No → With Hugo you can build a static site.\ +Yes → Build a static site with Hugo. + +No → This will cause Hugo to generate HTML files in the `public` directory.\ +Yes → Hugo generates HTML files in the `public` directory. + +Use second person instead of third person. + +No → Users should exercise caution when deleting files.\ +Better → You must be cautious when deleting files.\ +Best → Be cautious when deleting files. + +Minimize adverbs. + +No → Hugo is extremely fast.\ +Yes → Hugo is fast. + +> [!note] +> "It's an adverb, Sam. It's a lazy tool of a weak mind." (Outbreak, 1995). + +### Function and method descriptions + - Start descriptions in the functions and methods sections with "Returns", of for booelan values, "Reports whether". ++Start descriptions in the functions and methods sections with "Returns", or for boolean values, "Reports whether". + +### File paths and names + +Enclose directory names, file names, and file paths in backticks, except when used in: + +- Page titles +- Section headings (h1-h6) +- Definition list terms +- The `description` field in front matter + +### Miscellaneous + +Other best practices: + +- Introduce lists with a sentence or phrase, not directly under a heading. +- Avoid bold text; use [callouts](#callouts) for emphasis. +- Do not put description terms (`dt`) in backticks unless syntactically necessary. +- Do not use Hugo's `ref` or `relref` shortcodes. +- Prioritize current best practices over multiple options or historical information. +- Use short, focused code examples. +- Use [basic english] where possible for a global audience. + +## Front matter fields + +This site uses the front matter fields listed in the table below. + +Of the four required fields, only `title` and `description` require data. + +```text +title: The title +description: The description +categories: [] +keywords: [] +``` + +This example demonstrates the minimum required front matter fields. + +If quotation marks are required, prefer single quotes to double quotes when possible. + +Seq|Field|Description|Required +--:|:--|:--|:-- +1|`title`|The page title|:heavy_check_mark:| +2|`linkTitle`|A short version of the page title|| +3|`description`|A complete sentence describing the page|:heavy_check_mark:| +4|`categories`|An array of terms in the categories taxonomy|:heavy_check_mark: [^1]| +5|`keywords`|An array of keywords used to identify related content|:heavy_check_mark: [^1]| +6|`publishDate`|Applicable to news items: the publication date|| +7|`params.altTitle`|An alternate title: used in the "see also" panel if provided|| +8|`params.functions_and_methods.aliases`|Applicable to function and method pages: an array of alias names|| +9|`params.functions_and_methods.returnType`|Applicable to function and method pages: the data type returned|| +10|`params.functions_and_methods.signatures`|Applicable to function and method pages: an array of signatures|| +11|`params.hide_in_this_section`|Whether to hide the "in this section" panel|| +12|`params.minversion`|Applicable to the quick start page: the minimum Hugo version required|| +13|`params.permalink`|Reserved for use by the news content adapter|| +14|`params.reference (used in glossary term)`|Applicable to glossary entries: a URL for additional information|| +15|`params.show_publish_date`|Whether to show the `publishDate` when rendering the page|| +16|`weight`|The page weight|| +17|`aliases`|Previous URLs used to access this page|| +18|`expirydate`|The expiration date|| + +[^1]: The field is required, but its data is not. + +## Related content + +When available, the "See also" sidebar displays related pages using Hugo's [related content] feature, based on front matter keywords. We ensure consistent keyword usage by validating them against `data/keywords.yaml` during the build process. If a keyword is not found, you'll be alerted and must either modify the keyword or update the data file. This validation process helps to refine the related content for better results. + +If the title in the "See also" sidebar is ambiguous or the same as another page, you can define an alternate title in the front matter: + +{{< code-toggle file=hugo >}} +title = "Long descriptive title" +linkTitle = "Short title" +[params] +altTitle = "Whatever you want" +{{< /code-toggle >}} + +Use of the alternate title is limited to the "See also" sidebar. + +> [!note] +> Think carefully before setting the `altTitle`. Use it only when absolutely necessary. + +## Code examples + +With examples of template code: + +- Indent with two spaces. +- Insert a space after an opening action delimiter. +- Insert a space before a closing action delimiter. +- Do not add white space removal syntax to action delimiters unless required. For example, inline elements like `img` and `a` require whitespace removal on both sides. + +```go-html-template +{{ if eq $foo $bar }} + {{ fmt.Printf "%s is %s" $foo $bar }} +{{ end }} +``` + +### Fenced code blocks + +Always specify the language. + +When providing a Mardown example, set the code language to "text" to prevent +erroneous lexing/highlighting of shortcode calls. + +````text +```go-html-template +{{ if eq $foo "bar" }} + {{ print "foo is bar" }} +{{ end }} +``` +```` + +To include a filename header and copy-to-clipboard button: + +````text +```go-html-template {file="layouts/partials/foo.html" copy=true} +{{ if eq $foo "bar" }} + {{ print "foo is bar" }} +{{ end }} +``` +```` + +To wrap the code block within an initially-opened `details` element using a non-default summary: + +````text +```go-html-template {details=true open=true summary="layouts/partials/foo.html" copy=true} +{{ if eq $foo "bar" }} + {{ print "foo is bar" }} +{{ end }} +``` +```` + +### Shortcode calls + +Use this syntax : + +````text +```text +{{}} +{{%/*/* foo */*/%}} +``` +```` + +### Site configuration + +Use the [code-toggle shortcode](#code-toggle) to include site configuration examples: + +```text +{{}} +baseURL = 'https://example.org/' +languageCode = 'en-US' +title = 'My Site' +{{}} +``` + +### Front matter + +Use the [code-toggle shortcode](#code-toggle) to include front matter examples: + +```text +{{}} +title = 'My first post' +date = 2023-11-09T12:56:07-08:00 +draft = false +{{}} +``` + +## Callouts + +To visually emphasize important information, use callouts (admonitions). Callout types are case-insensitive. Effective March 8, 2025, we utilize only three of the five available types. + +- note (272 instances) +- warning (2 instances) +- caution (1 instance) + +Limiting the number of callout types helps us to use them consistently. + +```text +> [!note] +> Useful information that users should know, even when skimming content. +``` + +> [!note] +> Useful information that users should know, even when skimming content. + +```text +> [!warning] +> Urgent info that needs immediate user attention to avoid problems. +``` + +> [!warning] +> Urgent info that needs immediate user attention to avoid problems. + +```text +> [!caution] +> Advises about risks or negative outcomes of certain actions. +``` + +> [!caution] +> Advises about risks or negative outcomes of certain actions. + +```text +> [!tip] +> Helpful advice for doing things better or more easily. +``` + +> [!tip] +> Helpful advice for doing things better or more easily. + +```text +> [!important] +> Key information users need to know to achieve their goal. +``` + +> [!important] +> Key information users need to know to achieve their goal. + + + +## Shortcodes + +These shortcodes are commonly used throughout the documentation. Other shortcodes are available for specialized use. + +### code-toggle + +Use the `code-toggle` shortcode to display examples of site configuration, front matter, or data files. This shortcode takes these arguments: + +config +: (`string`) The section of `site.Data.docs.config` to render. + +copy +: (`bool`) Whether to display a copy-to-clipboard button. Default is `false`. + +datakey: +: (`string`) The section of `site.Data.docs` to render. + +file +: (`string`) The file name to display above the rendered code. Omit the file extension for site configuration examples. + +fm +: (`bool`) Whether to render the code as front matter. Default is `false`. + +skipHeader +: (`bool`) Whether to omit top-level key(s) when rendering a section of `site.Data.docs.config`. + +```text +{{}} +baseURL = 'https://example.org/' +languageCode = 'en-US' +title = 'My Site' +{{}} +``` + +### deprecated-in + +Use the `deprecated-in` shortcode to indicate that a feature is deprecated: + +```text +{{}} + +Use [`hugo.IsServer`] instead. + +[`hugo.IsServer`]: /functions/hugo/isserver/ +{{}} +``` + +### eturl + +Use the embedded template URL (`eturl`) shortcode to insert an absolute URL to the source code for an embedded template. The shortcode takes a single argument, the base file name of the template (omit the file extension). + +```text +This is a link to the [embedded alias template]. + +[embedded alias template]: {{%/* eturl alias */%}} +``` + +### glossary-term + +Use the `glossary-term` shortcode to insert the definition of the given glossary term. + +```text +{{%/* glossary-term scalar */%}} +``` + +### include + +Use the `include` shortcode to include content from another page. + +```text +{{%/* include "_common/glob-patterns.md" */%}} +``` + +### new-in + +Use the `new-in` shortcode to indicate a new feature: + +```text +{{}} +``` + +You can also include details: + +```text +{{}} +This is a new feature. +{{}} +``` + +## New features + +Use the [new-in shortcode](#new-in) to indicate a new feature: + +```text +{{}} +``` + +The "new in" label will be hidden if the specified version is older than a predefined threshold, based on differences in major and minor versions. See [details](https://github.com/gohugoio/hugoDocs/blob/master/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/new-in.html). + +## Deprecated features + +Use the [deprecated-in shorcode](#deprecated-in) shortcode to indicate that a feature is deprecated: + +```text +{{}} +Use [`hugo.IsServer`] instead. + +[`hugo.IsServer`]: /functions/hugo/isserver/ +{{}} +``` + +When deprecating a function or method, add something like this to front matter: + +{{< code-toggle file=content/something/foo.md fm=true >}} +expiryDate: 2027-02-17 # deprecated 2025-02-17 in v0.144.0 +{{< /code-toggle >}} + +Set the `expiryDate` to two years from the date of deprecation, and add a brief front matter comment to explain the setting. + +## GitHub workflow + +> [!note] +> This section assumes that you have a working knowledge of Git and GitHub, and are comfortable working on the command line. + +Use this workflow to create and submit pull requests. + +### Step 1 + +Fork the [documentation repository]. + +### Step 2 + +Clone your fork. + +### Step 3 + +Create a new branch with a descriptive name that includes the corresponding issue number, if any: + +```sh +git checkout -b restructure-foo-page-99999 +``` + +### Step 4 + +Make changes. + +### Step 5 + +Build the site locally to preview your changes. + +### Step 6 + +Commit your changes with a descriptive commit message: + +- Provide a summary on the first line, typically 50 characters or less, followed by a blank line. + - Begin the summary with one of `content`, `theme`, `config`, `all`, or `misc`, followed by a colon, a space, and a brief description of the change beginning with a capital letter + - Use imperative present tense +- Optionally, provide a detailed description where each line is 72 characters or less, followed by a blank line. +- Optionally, add one or more "Fixes" or "Closes" keywords, each on its own line, referencing the [issues] addressed by this change. + +For example: + +```text +git commit -m "content: Restructure the taxonomy page + +This restructures the taxonomy page by splitting topics into logical +sections, each with one or more examples. + +Fixes #9999 +Closes #9998" +``` + +### Step 7 + +Push the new branch to your fork of the documentation repository. + +### Step 8 + +Visit the [documentation repository] and create a pull request (PR). + +### Step 9 + +A project maintainer will review your PR and may request changes. You may delete your branch after the maintainer merges your PR. + +[ATX]: https://spec.commonmark.org/0.30/#atx-headings +[basic english]: https://simple.wikipedia.org/wiki/Basic_English +[basic english]: https://simple.wikipedia.org/wiki/Basic_English +[developer documentation style guide]: https://developers.google.com/style +[documentation repository]: https://github.com/gohugoio/hugoDocs/ +[fenced code blocks]: https://spec.commonmark.org/0.30/#fenced-code-blocks +[glossary]: /quick-reference/glossary/ +[indented code blocks]: https://spec.commonmark.org/0.30/#indented-code-blocks +[issues]: https://github.com/gohugoio/hugoDocs/issues +[list items]: https://spec.commonmark.org/0.30/#list-items +[project repository]: https://github.com/gohugoio/hugo +[raw HTML]: https://spec.commonmark.org/0.30/#raw-html +[related content]: /content-management/related-content/ +[setext]: https://spec.commonmark.org/0.30/#setext-heading diff --cc docs/content/en/functions/collections/Where.md index 1df84afc4,000000000..84fd1d21e mode 100644,000000..100644 --- a/docs/content/en/functions/collections/Where.md +++ b/docs/content/en/functions/collections/Where.md @@@ -1,422 -1,0 +1,419 @@@ +--- +title: collections.Where +description: Returns the given collection, removing elements that do not satisfy the comparison condition. +categories: [] +keywords: [] +params: + functions_and_methods: + aliases: [where] + returnType: any + signatures: ['collections.Where COLLECTION KEY [OPERATOR] VALUE'] +aliases: [/functions/where] +--- + +The `where` function returns the given collection, removing elements that do not satisfy the comparison condition. The comparison condition is composed of the `KEY`, `OPERATOR`, and `VALUE` arguments: + +```text +collections.Where COLLECTION KEY [OPERATOR] VALUE + -------------------- + comparison condition +``` + +Hugo will test for equality if you do not provide an `OPERATOR` argument. For example: + +```go-html-template +{{ $pages := where .Site.RegularPages "Section" "books" }} +{{ $books := where .Site.Data.books "genres" "suspense" }} +``` + +## Arguments + +The where function takes three or four arguments. The `OPERATOR` argument is optional. + +COLLECTION +: (`any`) A [page collection](g) or a [slice](g) of [maps](g). + +KEY +: (`string`) The key of the page or map value to compare with `VALUE`. With page collections, commonly used comparison keys are `Section`, `Type`, and `Params`. To compare with a member of the page `Params` map, [chain](g) the subkey as shown below: + +```go-html-template +{{ $result := where .Site.RegularPages "Params.foo" "bar" }} +``` + +OPERATOR +: (`string`) The logical comparison [operator](#operators). + +VALUE +: (`any`) The value with which to compare. The values to compare must have comparable data types. For example: + +Comparison|Result +:--|:-- +`"123" "eq" "123"`|`true` +`"123" "eq" 123`|`false` +`false "eq" "false"`|`false` +`false "eq" false`|`true` + +When one or both of the values to compare is a slice, use the `in`, `not in`, or `intersect` operators as described below. + +## Operators + +Use any of the following logical operators: + +`=`, `==`, `eq` +: (`bool`) Reports whether the given field value is equal to `VALUE`. + +`!=`, `<>`, `ne` +: (`bool`) Reports whether the given field value is not equal to `VALUE`. + +`>=`, `ge` +: (`bool`) Reports whether the given field value is greater than or equal to `VALUE`. + +`>`, `gt` +: `true` Reports whether the given field value is greater than `VALUE`. + +`<=`, `le` +: (`bool`) Reports whether the given field value is less than or equal to `VALUE`. + +`<`, `lt` +: (`bool`) Reports whether the given field value is less than `VALUE`. + +`in` +: (`bool`) Reports whether the given field value is a member of `VALUE`. Compare string to slice, or string to string. See [details](/functions/collections/in). + +`not in` +: (`bool`) Reports whether the given field value is not a member of `VALUE`. Compare string to slice, or string to string. See [details](/functions/collections/in). + +`intersect` +: (`bool`) Reports whether the given field value (a slice) contains one or more elements in common with `VALUE`. See [details](/functions/collections/intersect). + +`like` - : {{< new-in 0.116.0 />}} +: (`bool`) Reports whether the given field value matches the [regular expression](g) specified in `VALUE`. Use the `like` operator to compare `string` values. The `like` operator returns `false` when comparing other data types to the regular expression. + +> [!note] +> The examples below perform comparisons within a page collection, but the same comparisons are applicable to a slice of maps. + +## String comparison + +Compare the value of the given field to a [`string`](g): + +```go-html-template +{{ $pages := where .Site.RegularPages "Section" "eq" "books" }} +{{ $pages := where .Site.RegularPages "Section" "ne" "books" }} +``` + +## Numeric comparison + +Compare the value of the given field to an [`int`](g) or [`float`](g): + +```go-html-template +{{ $books := where site.RegularPages "Section" "eq" "books" }} + +{{ $pages := where $books "Params.price" "eq" 42 }} +{{ $pages := where $books "Params.price" "ne" 42.67 }} +{{ $pages := where $books "Params.price" "ge" 42 }} +{{ $pages := where $books "Params.price" "gt" 42.67 }} +{{ $pages := where $books "Params.price" "le" 42 }} +{{ $pages := where $books "Params.price" "lt" 42.67 }} +``` + +## Boolean comparison + +Compare the value of the given field to a [`bool`](g): + +```go-html-template +{{ $books := where site.RegularPages "Section" "eq" "books" }} + +{{ $pages := where $books "Params.fiction" "eq" true }} +{{ $pages := where $books "Params.fiction" "eq" false }} +{{ $pages := where $books "Params.fiction" "ne" true }} +{{ $pages := where $books "Params.fiction" "ne" false }} +``` + +## Member comparison + +Compare a [`scalar`](g) to a [`slice`](g). + +For example, to return a collection of pages where the `color` page parameter is either "red" or "yellow": + +```go-html-template +{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }} + +{{ $colors := slice "red" "yellow" }} +{{ $pages := where $fruit "Params.color" "in" $colors }} +``` + +To return a collection of pages where the "color" page parameter is neither "red" nor "yellow": + +```go-html-template +{{ $fruit := where site.RegularPages "Section" "eq" "fruit" }} + +{{ $colors := slice "red" "yellow" }} +{{ $pages := where $fruit "Params.color" "not in" $colors }} +``` + +## Intersection comparison + +Compare a `slice` to a `slice`, returning collection elements with common values. This is frequently used when comparing taxonomy terms. + +For example, to return a collection of pages where any of the terms in the "genres" taxonomy are "suspense" or "romance": + +```go-html-template +{{ $books := where site.RegularPages "Section" "eq" "books" }} + +{{ $genres := slice "suspense" "romance" }} +{{ $pages := where $books "Params.genres" "intersect" $genres }} +``` + +## Regular expression comparison + - {{< new-in 0.116.0 />}} - +To return a collection of pages where the "author" page parameter begins with either "victor" or "Victor": + +```go-html-template +{{ $pages := where .Site.RegularPages "Params.author" "like" `(?i)^victor` }} +``` + +{{% include "/_common/functions/regular-expressions.md" %}} + +> [!note] +> Use the `like` operator to compare string values. Comparing other data types will result in an empty collection. + +## Date comparison + +### Predefined dates + +There are four predefined front matter dates: [`date`], [`publishDate`], [`lastmod`], and [`expiryDate`]. Regardless of the front matter data format (TOML, YAML, or JSON) these are [`time.Time`] values, allowing precise comparisons. + +For example, to return a collection of pages that were created before the current year: + +```go-html-template +{{ $startOfYear := time.AsTime (printf "%d-01-01" now.Year) }} +{{ $pages := where .Site.RegularPages "Date" "lt" $startOfYear }} +``` + +### Custom dates + +With custom front matter dates, the comparison depends on the front matter data format (TOML, YAML, or JSON). + +> [!note] +> Using TOML for pages with custom front matter dates enables precise date comparisons. + +With TOML, date values are first-class citizens. TOML has a date data type while JSON and YAML do not. If you quote a TOML date, it is a string. If you do not quote a TOML date value, it is [`time.Time`] value, enabling precise comparisons. + +In the TOML example below, note that the event date is not quoted. + +```text {file="content/events/2024-user-conference.md"} ++++ +title = '2024 User Conference" +eventDate = 2024-04-01 ++++ +``` + +To return a collection of future events: + +```go-html-template +{{ $events := where .Site.RegularPages "Type" "events" }} +{{ $futureEvents := where $events "Params.eventDate" "gt" now }} +``` + +When working with YAML or JSON, or quoted TOML values, custom dates are strings; you cannot compare them with `time.Time` values. String comparisons may be possible if the custom date layout is consistent from one page to the next. To be safe, filter the pages by ranging through the collection: + +```go-html-template +{{ $events := where .Site.RegularPages "Type" "events" }} +{{ $futureEvents := slice }} +{{ range $events }} + {{ if gt (time.AsTime .Params.eventDate) now }} + {{ $futureEvents = $futureEvents | append . }} + {{ end }} +{{ end }} +``` + +## Nil comparison + +To return a collection of pages where the "color" parameter is present in front matter, compare to `nil`: + +```go-html-template +{{ $pages := where .Site.RegularPages "Params.color" "ne" nil }} +``` + +To return a collection of pages where the "color" parameter is not present in front matter, compare to `nil`: + +```go-html-template +{{ $pages := where .Site.RegularPages "Params.color" "eq" nil }} +``` + +In both examples above, note that `nil` is not quoted. + +## Nested comparison + +These are equivalent: + +```go-html-template +{{ $pages := where .Site.RegularPages "Type" "tutorials" }} +{{ $pages = where $pages "Params.level" "eq" "beginner" }} +``` + +```go-html-template +{{ $pages := where (where .Site.RegularPages "Type" "tutorials") "Params.level" "eq" "beginner" }} +``` + +## Portable section comparison + +Useful for theme authors, avoid hardcoding section names by using the `where` function with the [`MainSections`] method on a `Site` object. + +```go-html-template +{{ $pages := where .Site.RegularPages "Section" "in" .Site.MainSections }} +``` + +With this construct, a theme author can instruct users to specify their main sections in the site configuration: + +{{< code-toggle file=hugo >}} +mainSections = ['blog','galleries'] +{{< /code-toggle >}} + +If `mainSections` is not defined in the site configuration, the `MainSections` method returns a slice with one element---the top-level section with the most pages. + +## Boolean/undefined comparison + +Consider this site content: + +```text +content/ +├── posts/ +│ ├── _index.md +│ ├── post-1.md <-- front matter: exclude = false +│ ├── post-2.md <-- front matter: exclude = true +│ └── post-3.md <-- front matter: exclude not defined +└── _index.md +``` + +The first two pages have an "exclude" field in front matter, but the last page does not. When testing for _equality_, the third page is _excluded_ from the result. When testing for _inequality_, the third page is _included_ in the result. + +### Equality test + +This template: + +```go-html-template + +``` + +Is rendered to: + +```html + +``` + +This template: + +```go-html-template + +``` + +Is rendered to: + +```html + +``` + +### Inequality test + +This template: + +```go-html-template + +``` + +Is rendered to: + +```html + +``` + +This template: + +```go-html-template + +``` + +Is rendered to: + +```html + +``` + +To exclude a page with an undefined field from a boolean _inequality_ test: + +1. Create a collection using a boolean comparison +1. Create a collection using a nil comparison +1. Subtract the second collection from the first collection using the [`collections.Complement`] function. + +This template: + +```go-html-template +{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" true }} +{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }} + +``` + +Is rendered to: + +```html + +``` + +This template: + +```go-html-template +{{ $p1 := where .Site.RegularPages "Params.exclude" "ne" false }} +{{ $p2 := where .Site.RegularPages "Params.exclude" "eq" nil }} + +``` + +Is rendered to: + +```html + +``` + +[`collections.Complement`]: /functions/collections/complement/ +[`date`]: /methods/page/date/ +[`lastmod`]: /methods/page/lastmod/ +[`MainSections`]: /methods/site/mainsections/ +[`time.Time`]: https://pkg.go.dev/time#Time diff --cc docs/content/en/functions/css/Sass.md index 1d5487130,000000000..03a4c7451 mode 100644,000000..100644 --- a/docs/content/en/functions/css/Sass.md +++ b/docs/content/en/functions/css/Sass.md @@@ -1,234 -1,0 +1,204 @@@ +--- +title: css.Sass +description: Transpiles Sass to CSS. +categories: [] +keywords: [] +params: + functions_and_methods: + aliases: [toCSS] + returnType: resource.Resource + signatures: ['css.Sass [OPTIONS] RESOURCE'] +--- + +{{< new-in 0.128.0 />}} + - ```go-html-template - {{ with resources.Get "sass/main.scss" }} - {{ $opts := dict - "enableSourceMap" (not hugo.IsProduction) - "outputStyle" (cond hugo.IsProduction "compressed" "expanded") - "targetPath" "css/main.css" - "transpiler" "libsass" - }} - {{ with . | toCSS $opts }} - {{ if hugo.IsProduction }} - {{ with . | fingerprint }} - - {{ end }} - {{ else }} - - {{ end }} - {{ end }} - {{ end }} - ``` - +Transpile Sass to CSS using the LibSass transpiler included in Hugo's extended and extended/deploy editions, or [install Dart Sass](#dart-sass) to use the latest features of the Sass language. + +Sass has two forms of syntax: [SCSS] and [indented]. Hugo supports both. + +[scss]: https://sass-lang.com/documentation/syntax#scss +[indented]: https://sass-lang.com/documentation/syntax#the-indented-syntax + +## Options + - transpiler - : (`string`) The transpiler to use, either `libsass` (default) or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass) below. - - targetPath - : (`string`) If not set, the transformed resource's target path will be the original path of the asset file with its extension replaced by `.css`. - - vars - : (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/). - - ```scss - // LibSass - @import "hugo:vars"; ++enableSourceMap ++: (`bool`) Whether to generate a source map. Default is `false`. + - // Dart Sass - @use "hugo:vars" as v; - ``` ++includePaths ++: (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements. + +outputStyle - : (`string`) Output styles available to LibSass include `nested` (default), `expanded`, `compact`, and `compressed`. Output styles available to Dart Sass include `expanded` (default) and `compressed`. ++: (`string`) The output style of the resulting CSS. With LibSass, one of `nested` (default), `expanded`, `compact`, or `compressed`. With Dart Sass, either `expanded` (default) or `compressed`. + +precision - : (`int`) Precision of floating point math. Not applicable to Dart Sass. ++: (`int`) The precision of floating point math. Applicable to LibSass. Default is `8`. + - enableSourceMap - : (`bool`) Whether to generate a source map. Default is `false`. ++silenceDeprecations ++: {{< new-in 0.139.0 />}} ++: (`slice`) A slice of deprecation IDs to silence. IDs are enclosed in brackets within Dart Sass warning messages (e.g., `import` in `WARN Dart Sass: DEPRECATED [import]`). Applicable to Dart Sass. Default is `false`. ++ ++silenceDependencyDeprecations ++: {{< new-in 0.146.0 />}} ++: (`bool`) Whether to silence deprecation warnings from dependencies, where a dependency is considered any file transitively imported through a load path. This does not apply to `@warn` or `@debug` rules.Default is `false`. + +sourceMapIncludeSources - : (`bool`) Whether to embed sources in the generated source map. Not applicable to LibSass. Default is `false`. ++: (`bool`) Whether to embed sources in the generated source map. Applicable to Dart Sass. Default is `false`. + - includePaths - : (`slice`) A slice of paths, relative to the project root, that the transpiler will use when resolving `@use` and `@import` statements. ++targetPath ++: (`string`) The publish path for the transformed resource, relative to the[`publishDir`]. If unset, the target path defaults to the asset's original path with a `.css` extension. ++ ++transpiler ++: (`string`) The transpiler to use, either `libsass` or `dartsass`. Hugo's extended and extended/deploy editions include the LibSass transpiler. To use the Dart Sass transpiler, see the [installation instructions](#dart-sass). Default is `libsass`. ++ ++vars ++: (`map`) A map of key-value pairs that will be available in the `hugo:vars` namespace. Useful for [initializing Sass variables from Hugo templates](https://discourse.gohugo.io/t/42053/). ++ ++ ```scss ++ // LibSass ++ @import "hugo:vars"; ++ ++ // Dart Sass ++ @use "hugo:vars" as v; ++ ``` + - ```go-html-template - {{ $opts := dict - "transpiler" "dartsass" - "targetPath" "css/style.css" - "vars" site.Params.styles - "enableSourceMap" (not hugo.IsProduction) - "includePaths" (slice "node_modules/bootstrap/scss") - }} - {{ with resources.Get "sass/main.scss" | toCSS $opts | minify | fingerprint }} - ++## Example ++ ++```go-html-template {copy=true} ++{{ with resources.Get "sass/main.scss" }} ++ {{ $opts := dict ++ "enableSourceMap" (not hugo.IsProduction) ++ "outputStyle" (cond hugo.IsProduction "compressed" "expanded") ++ "targetPath" "css/main.css" ++ "transpiler" "dartsass" ++ "vars" site.Params.styles ++ "includePaths" (slice "node_modules/bootstrap/scss") ++ }} ++ {{ with . | toCSS $opts }} ++ {{ if hugo.IsProduction }} ++ {{ with . | fingerprint }} ++ ++ {{ end }} ++ {{ else }} ++ ++ {{ end }} ++ {{ end }} +{{ end }} +``` + - silenceDeprecations - : (`slice`) {{< new-in 0.139.0 />}} A slice of deprecation IDs to silence. The deprecation IDs are printed to in the warning message, e.g "import" in `WARN Dart Sass: DEPRECATED [import] ...`. This is for Dart Sass only. - +## Dart Sass + +Hugo's extended and extended/deploy editions include [LibSass] to transpile Sass to CSS. In 2020, the Sass team deprecated LibSass in favor of [Dart Sass]. + +Use the latest features of the Sass language by installing Dart Sass in your development and production environments. + +### Installation overview + +Dart Sass is compatible with Hugo v0.114.0 and later. + +If you have been using Embedded Dart Sass[^1] with Hugo v0.113.0 and earlier, uninstall Embedded Dart Sass, then install Dart Sass. If you have installed both, Hugo will use Dart Sass. + +If you install Hugo as a [Snap package] there is no need to install Dart Sass. The Hugo Snap package includes Dart Sass. + +[^1]: In 2023, the Sass team deprecated Embedded Dart Sass in favor of Dart Sass. + +### Installing in a development environment + +When you install Dart Sass somewhere in your PATH, Hugo will find it. + +OS|Package manager|Site|Installation +:--|:--|:--|:-- +Linux|Homebrew|[brew.sh]|`brew install sass/sass/sass` +Linux|Snap|[snapcraft.io]|`sudo snap install dart-sass` +macOS|Homebrew|[brew.sh]|`brew install sass/sass/sass` +Windows|Chocolatey|[chocolatey.org]|`choco install sass` +Windows|Scoop|[scoop.sh]|`scoop install sass` + +You may also install [prebuilt binaries] for Linux, macOS, and Windows. + +Run `hugo env` to list the active transpilers. + ++> [!note] ++> If you build Hugo from source and run `mage test -v`, the test will fail if you install Dart Sass as a Snap package. This is due to the Snap package's strict confinement model. ++ +### Installing in a production environment + +For [CI/CD](g) deployments (e.g., GitHub Pages, GitLab Pages, Netlify, etc.) you must edit the workflow to install Dart Sass before Hugo builds the site[^2]. Some providers allow you to use one of the package managers above, or you can download and extract one of the prebuilt binaries. + +[^2]: You do not have to do this if (a) you have not modified the assets cache location, and (b) you have not set `useResourceCacheWhen` to `never` in your [site configuration], and (c) you add and commit your `resources` directory to your repository. + +#### GitHub Pages + +To install Dart Sass for your builds on GitHub Pages, add this step to the GitHub Pages workflow file: + +```yaml +- name: Install Dart Sass + run: sudo snap install dart-sass +``` + - If you are using GitHub Pages for the first time with your repository, GitHub provides a [starter workflow] for Hugo that includes Dart Sass. This is the simplest way to get started. - +#### GitLab Pages + +To install Dart Sass for your builds on GitLab Pages, the `.gitlab-ci.yml` file should look something like this: + +```yaml +variables: + HUGO_VERSION: 0.144.2 + DART_SASS_VERSION: 1.85.0 + GIT_DEPTH: 0 + GIT_STRATEGY: clone + GIT_SUBMODULE_STRATEGY: recursive + TZ: America/Los_Angeles +image: + name: golang:1.20-buster +pages: + script: + # Install Dart Sass + - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz + - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz + - cp -r dart-sass/* /usr/local/bin + - rm -rf dart-sass* + # Install Hugo + - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb + - apt install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb + - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb + # Build + - hugo --gc --minify + artifacts: + paths: + - public + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH +``` + +#### Netlify + +To install Dart Sass for your builds on Netlify, the `netlify.toml` file should look something like this: + +```toml +[build.environment] +HUGO_VERSION = "0.144.2" +DART_SASS_VERSION = "1.85.0" +NODE_VERSION = "22" +TZ = "America/Los_Angeles" + +[build] +publish = "public" +command = """\ + curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \ + tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \ + rm dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \ + export PATH=/opt/build/repo/dart-sass:$PATH && \ + hugo --gc --minify \ + """ +``` + - ### Example - - To transpile with Dart Sass, set `transpiler` to `dartsass` in the options map passed to `css.Sass`. For example: - - ```go-html-template - {{ with resources.Get "sass/main.scss" }} - {{ $opts := dict - "enableSourceMap" (not hugo.IsProduction) - "outputStyle" (cond hugo.IsProduction "compressed" "expanded") - "targetPath" "css/main.css" - "transpiler" "dartsass" - }} - {{ with . | toCSS $opts }} - {{ if hugo.IsProduction }} - {{ with . | fingerprint }} - - {{ end }} - {{ else }} - - {{ end }} - {{ end }} - {{ end }} - ``` - - ### Miscellaneous - - If you build Hugo from source and run `mage test -v`, the test will fail if you install Dart Sass as a Snap package. This is due to the Snap package's strict confinement model. - +[brew.sh]: https://brew.sh/ +[chocolatey.org]: https://community.chocolatey.org/packages/sass +[dart sass]: https://sass-lang.com/dart-sass +[libsass]: https://sass-lang.com/libsass +[prebuilt binaries]: https://github.com/sass/dart-sass/releases/latest +[scoop.sh]: https://scoop.sh/#/apps?q=sass +[site configuration]: /configuration/build/ +[snap package]: /installation/linux/#snap +[snapcraft.io]: https://snapcraft.io/dart-sass +[starter workflow]: https://github.com/actions/starter-workflows/blob/main/pages/hugo.yml ++[`publishDir`]: /configuration/all/#publishdir diff --cc docs/content/en/functions/go-template/template.md index dac1fa3be,000000000..053cfcc22 mode 100644,000000..100644 --- a/docs/content/en/functions/go-template/template.md +++ b/docs/content/en/functions/go-template/template.md @@@ -1,46 -1,0 +1,70 @@@ +--- +title: template +description: Executes the given template, optionally passing context. +categories: [] +keywords: [] +params: + functions_and_methods: + aliases: [] + returnType: + signatures: ['template NAME [CONTEXT]'] +--- + - Use the `template` function to execute [embedded templates]. For example: ++Use the `template` function to execute any of these [embedded templates](g): ++ ++- [`disqus.html`] ++- [`google_analytics.html`] ++- [`opengraph.html`] ++- [`pagination.html`] ++- [`schema.html`] ++- [`twitter_cards.html`] ++ ++ ++ ++For example: + +```go-html-template +{{ range (.Paginate .Pages).Pages }} +

{{ .LinkTitle }}

+{{ end }} +{{ template "_internal/pagination.html" . }} +``` + +You can also use the `template` function to execute a defined template: + +```go-html-template +{{ template "foo" (dict "answer" 42) }} + +{{ define "foo" }} + {{ printf "The answer is %v." .answer }} +{{ end }} +``` + +The example above can be rewritten using an [inline partial] template: + +```go-html-template +{{ partial "inline/foo.html" (dict "answer" 42) }} + +{{ define "partials/inline/foo.html" }} + {{ printf "The answer is %v." .answer }} +{{ end }} +``` + ++The key distinctions between the preceding two examples are: ++ ++1. Inline partials are globally scoped. That means that an inline partial defined in _one_ template may be called from _any_ template. ++2. Leveraging the [`partialCached`] function when calling an inline partial allows for performance optimization through result caching. ++3. An inline partial can [`return`] a value of any data type instead of rendering a string. ++ +{{% include "/_common/functions/go-template/text-template.md" %}} + ++[`disqus.html`]: /templates/embedded/#disqus ++[`google_analytics.html`]: /templates/embedded/#google-analytics ++[`opengraph.html`]: /templates/embedded/#open-graph ++[`pagination.html`]: /templates/embedded/#pagination ++[`partialCached`]: /functions/partials/includecached/ +[`partial`]: /functions/partials/include/ ++[`return`]: /functions/go-template/return/ ++[`schema.html`]: /templates/embedded/#schema ++[`twitter_cards.html`]: /templates/embedded/#x-twitter-cards +[inline partial]: /templates/partial/#inline-partials - [embedded templates]: /templates/embedded/ diff --cc docs/content/en/functions/templates/Current.md index 000000000,000000000..805aeec05 new file mode 100644 --- /dev/null +++ b/docs/content/en/functions/templates/Current.md @@@ -1,0 -1,0 +1,155 @@@ ++--- ++title: templates.Current ++description: Returns information about the currently executing template. ++categories: [] ++keywords: [] ++params: ++ functions_and_methods: ++ aliases: [] ++ returnType: tpl.CurrentTemplateInfo ++ signatures: [templates.Current] ++--- ++ ++> [!note] ++> This function is experimental and subject to change. ++ ++{{< new-in 0.146.0 />}} ++ ++The `templates.Current` function provides introspection capabilities, allowing you to access details about the currently executing templates. This is useful for debugging complex template hierarchies and understanding the flow of execution during rendering. ++ ++## Methods ++ ++Ancestors ++: (`tpl.CurrentTemplateInfos`) Returns a slice containing information about each template in the current execution chain, starting from the parent of the current template and going up towards the initial template called. It excludes any base template applied via `define` and `block`. You can chain the `Reverse` method to this result to get the slice in chronological execution order. ++ ++Base ++: (`tpl.CurrentTemplateInfoCommonOps`) Returns an object representing the base template that was applied to the current template, if any. This may be `nil`. ++ ++Filename ++: (`string`) Returns the absolute path of the current template. This will be empty for embedded templates. ++ ++Name ++: (`string`) Returns the name of the current template. This is usually the path relative to the layouts directory. ++ ++Parent ++: (`tpl.CurrentTemplateInfo`) Returns an object representing the parent of the current template, if any. This may be `nil`. ++ ++## Examples ++ ++The examples below help visualize template execution and require a `debug` parameter set to `true` in your site configuration: ++ ++{{< code-toggle file=hugo >}} ++[params] ++debug = true ++{{< /code-toggle >}} ++ ++### Boundaries ++ ++To visually mark where a template begins and ends execution: ++ ++```go-html-template {file="layouts/_default/single.html"} ++{{ define "main" }} ++ {{ if site.Params.debug }} ++
[entering {{ templates.Current.Filename }}]
++ {{ end }} ++ ++

{{ .Title }}

++ {{ .Content }} ++ ++ {{ if site.Params.debug }} ++
[leaving {{ templates.Current.Filename }}]
++ {{ end }} ++{{ end }} ++``` ++ ++### Call stack ++ ++To display the chain of templates that led to the current one, create a partial template that iterates through its ancestors: ++ ++```go-html-template {file="layouts/partials/template-call-stack.html" copy=true} ++{{ with templates.Current }} ++
++ {{ range .Ancestors }} ++ {{ .Filename }}
++ {{ with .Base }} ++ {{ .Filename }}
++ {{ end }} ++ {{ end }} ++
++{{ end }} ++``` ++ ++Then call the partial from any template: ++ ++```go-html-template {file="layouts/partials/footer/copyright.html" copy=true} ++{{ if site.Params.debug }} ++ {{ partial "template-call-stack.html" . }} ++{{ end }} ++``` ++ ++The rendered template stack would look something like this: ++ ++```text ++/home/user/project/layouts/partials/footer/copyright.html ++/home/user/project/themes/foo/layouts/partials/footer.html ++/home/user/project/layouts/_default/single.html ++/home/user/project/themes/foo/layouts/_default/baseof.html ++``` ++ ++To reverse the order of the entries, chain the `Reverse` method to the `Ancestors` method: ++ ++```go-html-template {file="layouts/partials/template-call-stack.html" copy=true} ++{{ with templates.Current }} ++
++ {{ range .Ancestors.Reverse }} ++ {{ with .Base }} ++ {{ .Filename }}
++ {{ end }} ++ {{ .Filename }}
++ {{ end }} ++
++{{ end }} ++``` ++ ++### VS Code ++ ++To render links that, when clicked, will open the template in Microsoft Visual Studio Code, create a partial template with anchor elements that use the `vscode` URI scheme: ++ ++```go-html-template {file="layouts/partials/template-open-in-vs-code.html" copy=true} ++{{ with templates.Current.Parent }} ++
++ {{ .Name }} ++ {{ with .Base }} ++ {{ .Name }} ++ {{ end }} ++
++{{ end }} ++``` ++ ++Then call the partial from any template: ++ ++```go-html-template {file="layouts/_default/single.html" copy=true} ++{{ define "main" }} ++

{{ .Title }}

++ {{ .Content }} ++ ++ {{ if site.Params.debug }} ++ {{ partial "template-open-in-vs-code.html" . }} ++ {{ end }} ++{{ end }} ++``` ++ ++Use the same approach to render the entire call stack as links: ++ ++```go-html-template {file="layouts/partials/template-call-stack.html" copy=true} ++{{ with templates.Current }} ++
++ {{ range .Ancestors }} ++ {{ .Filename }}
++ {{ with .Base }} ++ {{ .Filename }}
++ {{ end }} ++ {{ end }} ++
++{{ end }} ++``` diff --cc docs/content/en/functions/time/In.md index 000000000,000000000..821eb99b7 new file mode 100644 --- /dev/null +++ b/docs/content/en/functions/time/In.md @@@ -1,0 -1,0 +1,30 @@@ ++--- ++title: time.In ++description: Returns the given date/time as represented in the specified IANA time zone. ++categories: [] ++keywords: [] ++params: ++ functions_and_methods: ++ aliases: [] ++ returnType: time.Time ++ signatures: [time.In TIMEZONE INPUT] ++--- ++ ++{{< new-in 0.146.0 />}} ++ ++The `time.In` function returns the given date/time as represented in the specified [IANA](g) time zone. ++ ++- If the time zone is an empty string or `UTC`, the time is returned in [UTC](g). ++- If the time zone is `Local`, the time is returned in the system's local time zone. ++- Otherwise, the time zone must be a valid IANA [time zone name]. ++ ++[time zone name]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List ++ ++```go-html-template ++{{ $layout := "2006-01-02T15:04:05-07:00" }} ++{{ $t := time.AsTime "2025-03-31T14:45:00-00:00" }} ++ ++{{ $t | time.In "America/Denver" | time.Format $layout }} → 2025-03-31T08:45:00-06:00 ++{{ $t | time.In "Australia/Adelaide" | time.Format $layout }} → 2025-04-01T01:15:00+10:30 ++{{ $t | time.In "Europe/Oslo" | time.Format $layout }} → 2025-03-31T16:45:00+02:00 ++``` diff --cc docs/content/en/functions/transform/Unmarshal.md index d159122f5,000000000..93168294c mode 100644,000000..100644 --- a/docs/content/en/functions/transform/Unmarshal.md +++ b/docs/content/en/functions/transform/Unmarshal.md @@@ -1,293 -1,0 +1,372 @@@ +--- +title: transform.Unmarshal +description: Parses serialized data and returns a map or an array. Supports CSV, JSON, TOML, YAML, and XML. +categories: [] +keywords: [] +params: + functions_and_methods: + aliases: [unmarshal] + returnType: any + signatures: ['transform.Unmarshal [OPTIONS] INPUT'] +aliases: [/functions/transform.unmarshal] +--- + +The input can be a string or a [resource](g). + +## Unmarshal a string + +```go-html-template +{{ $string := ` +title: Les Misérables +author: Victor Hugo +`}} + +{{ $book := unmarshal $string }} +{{ $book.title }} → Les Misérables +{{ $book.author }} → Victor Hugo +``` + +## Unmarshal a resource + +Use the `transform.Unmarshal` function with global, page, and remote resources. + +### Global resource + +A global resource is a file within the `assets` directory, or within any directory mounted to the `assets` directory. + +```text +assets/ +└── data/ + └── books.json +``` + +```go-html-template +{{ $data := dict }} +{{ $path := "data/books.json" }} +{{ with resources.Get $path }} + {{ with . | transform.Unmarshal }} + {{ $data = . }} + {{ end }} +{{ else }} + {{ errorf "Unable to get global resource %q" $path }} +{{ end }} + +{{ range where $data "author" "Victor Hugo" }} + {{ .title }} → Les Misérables +{{ end }} +``` + +### Page resource + +A page resource is a file within a [page bundle]. + +```text +content/ +├── post/ +│ └── book-reviews/ +│ ├── books.json +│ └── index.md +└── _index.md +``` + +```go-html-template +{{ $data := dict }} +{{ $path := "books.json" }} +{{ with .Resources.Get $path }} + {{ with . | transform.Unmarshal }} + {{ $data = . }} + {{ end }} +{{ else }} + {{ errorf "Unable to get page resource %q" $path }} +{{ end }} + +{{ range where $data "author" "Victor Hugo" }} + {{ .title }} → Les Misérables +{{ end }} +``` + +### Remote resource + +A remote resource is a file on a remote server, accessible via HTTP or HTTPS. + +```go-html-template +{{ $data := dict }} +{{ $url := "https://example.org/books.json" }} +{{ with try (resources.GetRemote $url) }} + {{ with .Err }} + {{ errorf "%s" . }} + {{ else with .Value }} + {{ $data = . | transform.Unmarshal }} + {{ else }} + {{ errorf "Unable to get remote resource %q" $url }} + {{ end }} +{{ end }} + +{{ range where $data "author" "Victor Hugo" }} + {{ .title }} → Les Misérables +{{ end }} +``` + +> [!note] +> When retrieving remote data, a misconfigured server may send a response header with an incorrect [Content-Type]. For example, the server may set the Content-Type header to `application/octet-stream` instead of `application/json`. +> +> In these cases, pass the resource `Content` through the `transform.Unmarshal` function instead of passing the resource itself. For example, in the above, do this instead: +> +> `{{ $data = .Content | transform.Unmarshal }}` + - ## Options ++## Working with CSV ++ ++### Options + +When unmarshaling a CSV file, provide an optional map of options. + +delimiter - : (`string`) The delimiter used, default is `,`. ++: (`string`) The delimiter used. Default is `,`. + +comment +: (`string`) The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored. + +lazyQuotes +: {{< new-in 0.122.0 />}} +: (`bool`) Whether to allow a quote in an unquoted field, or to allow a non-doubled quote in a quoted field. Default is `false`. + ++targetType ++: {{< new-in 0.146.7 />}} ++: (`string`) The target data type, either `slice` or `map`. Default is `slice`. ++ ++### Examples ++ ++The examples below use this CSV file: ++ ++```csv ++"name","type","breed","age" ++"Spot","dog","Collie",3 ++"Rover","dog","Boxer",5 ++"Felix","cat","Calico",7 ++``` ++ ++To render an HTML table from a CSV file: ++ +```go-html-template - {{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }} ++{{ $data := slice }} ++{{ $file := "pets.csv" }} ++{{ with or (.Resources.Get $file) (resources.Get $file) }} ++ {{ $opts := dict "targetType" "slice" }} ++ {{ $data = transform.Unmarshal $opts . }} ++{{ end }} ++ ++{{ with $data }} ++ ++ ++ ++ {{ range index . 0 }} ++ ++ {{ end }} ++ ++ ++ ++ {{ range . | after 1 }} ++ ++ {{ range . }} ++ ++ {{ end }} ++ ++ {{ end }} ++ ++
{{ . }}
{{ . }}
++{{ end }} ++``` ++ ++To extract a subset of the data, or to sort the data, unmarshal to a map instead of a slice: ++ ++```go-html-template ++{{ $data := slice }} ++{{ $file := "pets.csv" }} ++{{ with or (.Resources.Get $file) (resources.Get $file) }} ++ {{ $opts := dict "targetType" "map" }} ++ {{ $data = transform.Unmarshal $opts . }} ++{{ end }} ++ ++{{ with sort (where $data "type" "dog") "name" "asc" }} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ {{ range . }} ++ ++ ++ ++ ++ ++ ++ {{ end }} ++ ++
nametypebreedage
{{ .name }}{{ .type }}{{ .breed }}{{ .age }}
++{{ end }} +``` + +## Working with XML + +When unmarshaling an XML file, do not include the root node when accessing data. For example, after unmarshaling the RSS feed below, access the feed title with `$data.channel.title`. + +```xml + + + + Books on Example Site + https://example.org/books/ + Recent content in Books on Example Site + en-US + + + The Hunchback of Notre Dame + Written by Victor Hugo + https://example.org/books/the-hunchback-of-notre-dame/ + Mon, 09 Oct 2023 09:27:12 -0700 + https://example.org/books/the-hunchback-of-notre-dame/ + + + Les Misérables + Written by Victor Hugo + https://example.org/books/les-miserables/ + Mon, 09 Oct 2023 09:27:11 -0700 + https://example.org/books/les-miserables/ + + + +``` + +Get the remote data: + +```go-html-template +{{ $data := dict }} +{{ $url := "https://example.org/books/index.xml" }} +{{ with try (resources.GetRemote $url) }} + {{ with .Err }} + {{ errorf "%s" . }} + {{ else with .Value }} + {{ $data = . | transform.Unmarshal }} + {{ else }} + {{ errorf "Unable to get remote resource %q" $url }} + {{ end }} +{{ end }} +``` + +Inspect the data structure: + +```go-html-template +
{{ debug.Dump $data }}
+``` + +List the book titles: + +```go-html-template +{{ with $data.channel.item }} + +{{ end }} +``` + +Hugo renders this to: + +```html + +``` + +### XML attributes and namespaces + +Let's add a `lang` attribute to the `title` nodes of our RSS feed, and a namespaced node for the ISBN number: + +```xml + + + + Books on Example Site + https://example.org/books/ + Recent content in Books on Example Site + en-US + + + The Hunchback of Notre Dame + Written by Victor Hugo + 9780140443530 + https://example.org/books/the-hunchback-of-notre-dame/ + Mon, 09 Oct 2023 09:27:12 -0700 + https://example.org/books/the-hunchback-of-notre-dame/ + + + Les Misérables + Written by Victor Hugo + 9780451419439 + https://example.org/books/les-miserables/ + Mon, 09 Oct 2023 09:27:11 -0700 + https://example.org/books/les-miserables/ + + + +``` + +After retrieving the remote data, inspect the data structure: + +```go-html-template +
{{ debug.Dump $data }}
+``` + +Each item node looks like this: + +```json +{ + "description": "Written by Victor Hugo", + "guid": "https://example.org/books/the-hunchback-of-notre-dame/", + "link": "https://example.org/books/the-hunchback-of-notre-dame/", + "number": "9780140443530", + "pubDate": "Mon, 09 Oct 2023 09:27:12 -0700", + "title": { + "#text": "The Hunchback of Notre Dame", + "-lang": "en" + } +} +``` + +The title keys do not begin with an underscore or a letter---they are not valid [identifiers](g). Use the [`index`] function to access the values: + +```go-html-template +{{ with $data.channel.item }} + +{{ end }} +``` + +Hugo renders this to: + +```html + +``` + +[`index`]: /functions/collections/indexfunction/ +[Content-Type]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type +[page bundle]: /content-management/page-bundles/ diff --cc docs/content/en/host-and-deploy/host-on-github-pages/index.md index 4c00fbc8e,000000000..7c3201099 mode 100644,000000..100644 --- a/docs/content/en/host-and-deploy/host-on-github-pages/index.md +++ b/docs/content/en/host-and-deploy/host-on-github-pages/index.md @@@ -1,230 -1,0 +1,232 @@@ +--- +title: Host on GitHub Pages +description: Host your site on GitHub Pages. +categories: [] +keywords: [] +aliases: [/hosting-and-deployment/hosting-on-github/] +--- + +## Prerequisites + +Please complete the following tasks before continuing: + +1. [Create a GitHub account] +1. [Install Git] +1. [Create a Hugo site] and test it locally with `hugo server`. + +## Types of sites + +There are three types of GitHub Pages sites: project, user, and organization. Project sites are connected to a specific project hosted on GitHub. User and organization sites are connected to a specific account on GitHub.com. + +> [!note] +> See the [GitHub Pages documentation] to understand the requirements for repository ownership and naming. + +## Procedure + +### Step 1 + +Create a GitHub repository. + +### Step 2 + +Push your local repository to GitHub. + +### Step 3 + +Visit your GitHub repository. From the main menu choose **Settings** > **Pages**. In the center of your screen you will see this: + +![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 + +In your site configuration, change the location of the image cache to the [`cacheDir`] as shown below: + +{{< code-toggle file=hugo >}} +[caches.images] +dir = ":cacheDir/images" +{{< /code-toggle >}} + +See [configure file caches] for more information. + +### Step 6 + +Create a file named `hugo.yaml` in a directory named `.github/workflows`. + +```text +mkdir -p .github/workflows +touch .github/workflows/hugo.yaml +``` + +### Step 7 + +> [!note] +> The workflow below ensures Hugo's `cacheDir` is persistent, preserving modules, processed images, and [`resources.GetRemote`] data between builds. + +Copy and paste the YAML below into the file you created. Change the branch name and Hugo version as needed. + +```yaml {file=".github/workflows/hugo.yaml" copy=true} +# Sample workflow for building and deploying a Hugo site to GitHub Pages +name: Deploy Hugo site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: + - main + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +# Default to bash +defaults: + run: + shell: bash + +jobs: + # Build job + build: + runs-on: ubuntu-latest + env: + HUGO_VERSION: 0.145.0 + HUGO_ENVIRONMENT: production + TZ: America/Los_Angeles + steps: + - name: Install Hugo CLI + run: | + wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \ + && sudo dpkg -i ${{ runner.temp }}/hugo.deb + - name: Install Dart Sass + run: sudo snap install dart-sass + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 + - name: Setup Pages + id: pages + uses: actions/configure-pages@v5 + - name: Install Node.js dependencies + run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" + - name: Cache Restore + id: cache-restore + uses: actions/cache/restore@v4 + with: + path: | + ${{ runner.temp }}/hugo_cache + key: hugo-${{ github.run_id }} + restore-keys: + hugo- ++ - name: Configure Git ++ run: git config core.quotepath false + - name: Build with Hugo + run: | + hugo \ + --gc \ + --minify \ + --baseURL "${{ steps.pages.outputs.base_url }}/" \ + --cacheDir "${{ runner.temp }}/hugo_cache" + - name: Cache Save + id: cache-save + uses: actions/cache/save@v4 + with: + path: | + ${{ runner.temp }}/hugo_cache + key: ${{ steps.cache-restore.outputs.cache-primary-key }} + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./public + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 +``` + +### Step 8 + +Commit and push the change to your GitHub repository. + +```sh +git add -A +git commit -m "Create hugo.yaml" +git push +``` + +### Step 9 + +From GitHub's main menu, choose **Actions**. You will see something like this: + +![screen capture](gh-pages-3.png) +{style="max-width: 350px"} + +### Step 10 + +When GitHub has finished building and deploying your site, the color of the status indicator will change to green. + +![screen capture](gh-pages-4.png) +{style="max-width: 350px"} + +### Step 11 + +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. + +## Customize the workflow + +The example workflow above includes this step, which typically takes 10‑15 seconds: + +```yaml +- name: Install Dart Sass + run: sudo snap install dart-sass +``` + +You may remove this step if your site, themes, and modules do not transpile Sass to CSS using the [Dart Sass] transpiler. + +## Other resources + +- [Learn more about GitHub Actions](https://docs.github.com/en/actions) +- [Caching dependencies to speed up workflows](https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows) +- [Manage a custom domain for your GitHub Pages site](https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages) + +[Create a GitHub account]: https://github.com/signup +[Create a Hugo site]: /getting-started/quick-start/ +[Dart Sass]: /functions/css/sass/#dart-sass +[GitHub Pages documentation]: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites +[Install Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git +[`cacheDir`]: /configuration/all/#cachedir +[`resources.GetRemote`]: /functions/resources/getremote/ +[configure file caches]: /configuration/caches/ diff --cc docs/content/en/host-and-deploy/host-on-gitlab-pages.md index 4b308cc19,000000000..4750b0ff3 mode 100644,000000..100644 --- a/docs/content/en/host-and-deploy/host-on-gitlab-pages.md +++ b/docs/content/en/host-and-deploy/host-on-gitlab-pages.md @@@ -1,96 -1,0 +1,98 @@@ +--- +title: Host on GitLab Pages +description: Host your site on GitLab Pages. +categories: [] +keywords: [] +aliases: [/hosting-and-deployment/hosting-on-gitlab/] +--- + +## Assumptions + +- Working familiarity with Git for version control +- Completion of the Hugo [Quick Start] +- A [GitLab account](https://gitlab.com/users/sign_in) +- A Hugo website on your local machine that you are ready to publish + +## BaseURL + +The `baseURL` in your [site configuration](/configuration/) must reflect the full URL of your GitLab pages repository if you are using the default GitLab Pages URL (e.g., `https://.gitlab.io//`) and not a custom domain. + +## Configure GitLab CI/CD + +Define your [CI/CD](g) jobs by creating a `.gitlab-ci.yml` file in the root of your project. + +```yaml {file=".gitlab-ci.yml" copy=true} +variables: - DART_SASS_VERSION: 1.85.0 ++ DART_SASS_VERSION: 1.87.0 + GIT_DEPTH: 0 + GIT_STRATEGY: clone + GIT_SUBMODULE_STRATEGY: recursive - HUGO_VERSION: 0.144.2 - NODE_VERSION: 23.x ++ HUGO_VERSION: 0.146.7 ++ NODE_VERSION: 22.x + TZ: America/Los_Angeles +image: - name: golang:1.23.4-bookworm ++ name: golang:1.24.2-bookworm + +pages: + script: + # Install brotli + - apt-get update + - apt-get install -y brotli + # Install Dart Sass + - curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz + - tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz + - cp -r dart-sass/ /usr/local/bin + - rm -rf dart-sass* + - export PATH=/usr/local/bin/dart-sass:$PATH + # Install Hugo + - curl -LJO https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb + - apt-get install -y ./hugo_extended_${HUGO_VERSION}_linux-amd64.deb + - rm hugo_extended_${HUGO_VERSION}_linux-amd64.deb + # Install Node.js + - curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION} | bash - + - apt-get install -y nodejs + # Install Node.js dependencies + - "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true" ++ # Configure Git ++ - git config core.quotepath false + # Build + - hugo --gc --minify --baseURL ${CI_PAGES_URL} + # Compress + - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec gzip -f -k {} \; + - find public -type f -regex '.*\.\(css\|html\|js\|txt\|xml\)$' -exec brotli -f -k {} \; + artifacts: + paths: + - public + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH +``` + +## Push your Hugo website to GitLab + +Next, create a new repository on GitLab. It is *not* necessary to make the repository public. In addition, you might want to add `/public` to your .gitignore file, as there is no need to push compiled assets to GitLab or keep your output website in version control. + +```sh +# initialize new git repository +git init + +# add /public directory to our .gitignore file +echo "/public" >> .gitignore + +# commit and push code to master branch +git add . +git commit -m "Initial commit" +git remote add origin https://gitlab.com/YourUsername/your-hugo-site.git +git push -u origin master +``` + +## Wait for your page to build + +That's it! You can now follow the CI agent building your page at `https://gitlab.com///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/host-and-deploy/host-on-netlify/index.md index f3601331a,000000000..4c89a6c1e mode 100644,000000..100644 --- a/docs/content/en/host-and-deploy/host-on-netlify/index.md +++ b/docs/content/en/host-and-deploy/host-on-netlify/index.md @@@ -1,143 -1,0 +1,146 @@@ +--- +title: Host on Netlify +description: Host your site on Netlify. +categories: [] +keywords: [] +aliases: [/hosting-and-deployment/hosting-on-netlify/] +--- + +## Prerequisites + +Please complete the following tasks before continuing: + +1. [Create a Netlify account] +1. [Install Git] +1. [Create a Hugo site] and test it locally with `hugo server` +1. Commit the changes to your local repository +1. Push the local repository to your [GitHub], [GitLab], or [Bitbucket] account + +[Bitbucket]: https://bitbucket.org/product +[Create a Hugo site]: /getting-started/quick-start/ +[Create a Netlify account]: https://app.netlify.com/signup +[GitHub]: https://github.com +[GitLab]: https://about.gitlab.com/ +[Install Git]: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git + +## Procedure + +This procedure will enable continuous deployment from a GitHub repository. The procedure is essentially the same if you are using GitLab or Bitbucket. + +### Step 1 + +Log in to your Netlify account, navigate to the Sites page, press the **Add new site** button, and choose "Import an existing project" from the dropdown menu. + +### Step 2 + +Select your deployment method. + + ![screen capture](netlify-step-02.png) + +### Step 3 + +Authorize Netlify to connect with your GitHub account by pressing the **Authorize Netlify** button. + +![screen capture](netlify-step-03.png) + +### Step 4 + +Press the **Configure Netlify on GitHub** button. + +![screen capture](netlify-step-04.png) + +### Step 5 + +Install the Netlify app by selecting your GitHub account. + +![screen capture](netlify-step-05.png) + +### Step 6 + +Press the **Install** button. + +![screen capture](netlify-step-06.png) + +### Step 7 + +Click on the site's repository from the list. + +![screen capture](netlify-step-07.png) + +### Step 8 + +Set the site name and branch from which to deploy. + +![screen capture](netlify-step-08.png) + +### Step 9 + +Define the build settings, press the **Add environment variables** button, then press the **New variable** button. + +![screen capture](netlify-step-09.png) + +### Step 10 + +Create a new environment variable named `HUGO_VERSION` and set the value to the [latest version]. + +[latest version]: https://github.com/gohugoio/hugo/releases/latest + +![screen capture](netlify-step-10.png) + +### Step 11 + +Press the "Deploy my new site" button at the bottom of the page. + +![screen capture](netlify-step-11.png) + +### Step 12 + +At the bottom of the screen, wait for the deploy to complete, then click on the deploy log entry. + +![screen capture](netlify-step-12.png) + +### Step 13 + +Press the **Open production deploy** button to view the live site. + +![screen capture](netlify-step-13.png) + +## Configuration file + +In the procedure above we configured our site using the Netlify user interface. Most site owners find it easier to use a configuration file checked into source control. + +Create a new file named netlify.toml in the root of your project directory. In its simplest form, the configuration file might look like this: + +```toml {file="netlify.toml"} +[build.environment] - HUGO_VERSION = "0.144.2" ++GO_VERSION = "1.24" ++HUGO_VERSION = "0.146.7" +NODE_VERSION = "22" +TZ = "America/Los_Angeles" + +[build] +publish = "public" - command = "hugo --gc --minify" ++command = "git config core.quotepath false && hugo --gc --minify" +``` + +If your site requires Dart Sass to transpile Sass to CSS, the configuration file should look something like this: + +```toml {file="netlify.toml"} +[build.environment] - HUGO_VERSION = "0.144.2" - DART_SASS_VERSION = "1.85.0" ++DART_SASS_VERSION = "1.87.0" ++GO_VERSION = "1.24" ++HUGO_VERSION = "0.146.7" +NODE_VERSION = "22" +TZ = "America/Los_Angeles" + +[build] +publish = "public" +command = """\ + curl -LJO https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \ + tar -xf dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \ + rm dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz && \ + export PATH=/opt/build/repo/dart-sass:$PATH && \ ++ git config core.quotepath false && \ + hugo --gc --minify \ + """ +``` diff --cc docs/content/en/installation/linux.md index 731cfce4c,000000000..591bf0818 mode 100644,000000..100644 --- a/docs/content/en/installation/linux.md +++ b/docs/content/en/installation/linux.md @@@ -1,202 -1,0 +1,218 @@@ +--- +title: Linux +description: Install Hugo on Linux. +categories: [] +keywords: [] +weight: 20 +--- + +## Editions + +{{% include "/_common/installation/01-editions.md" %}} + +Unless your specific deployment needs require the extended/deploy edition, we recommend the extended edition. + +{{% include "/_common/installation/02-prerequisites.md" %}} + +{{% include "/_common/installation/03-prebuilt-binaries.md" %}} + +## Package managers + +### Snap + +[Snap] is a free and open-source package manager for Linux. Available for [most distributions], snap packages are simple to install and are automatically updated. + +The Hugo snap package is [strictly confined]. Strictly confined snaps run in complete isolation, up to a minimal access level that's deemed always safe. The sites you create and build must be located within your home directory, or on removable media. + +To install the extended edition of Hugo: + +```sh +sudo snap install hugo +``` + - To enable or revoke access to removable media: ++To control automatic updates: + +```sh ++# disable automatic updates ++sudo snap refresh --hold hugo ++ ++# enable automatic updates ++sudo snap refresh --unhold hugo ++``` ++ ++To control access to removable media: ++ ++```sh ++# allow access +sudo snap connect hugo:removable-media ++ ++# revoke access +sudo snap disconnect hugo:removable-media +``` + - To enable or revoke access to SSH keys: ++To control access to SSH keys: + +```sh ++# allow access +sudo snap connect hugo:ssh-keys ++ ++# revoke access +sudo snap disconnect hugo:ssh-keys +``` + +{{% include "/_common/installation/homebrew.md" %}} + +## Repository packages + +Most Linux distributions maintain a repository for commonly installed applications. + +> [!note] +> The Hugo version available in package repositories varies based on Linux distribution and release, and in some cases will not be the [latest version]. +> +> Use one of the other installation methods if your package repository does not provide the desired version. + +### Alpine Linux + +To install the extended edition of Hugo on [Alpine Linux]: + +```sh +doas apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community hugo +``` + +### Arch Linux + +Derivatives of the [Arch Linux] distribution of Linux include [EndeavourOS], [Garuda Linux], [Manjaro], and others. To install the extended edition of Hugo: + +```sh +sudo pacman -S hugo +``` + +### Debian + +Derivatives of the [Debian] distribution of Linux include [elementary OS], [KDE neon], [Linux Lite], [Linux Mint], [MX Linux], [Pop!_OS], [Ubuntu], [Zorin OS], and others. To install the extended edition of Hugo: + +```sh +sudo apt install hugo +``` + +You can also download Debian packages from the [latest release] page. + +### Exherbo + +To install the extended edition of Hugo on [Exherbo]: + +1. Add this line to /etc/paludis/options.conf: + + ```text + www-apps/hugo extended + ``` + +1. Install using the Paludis package manager: + + ```sh + cave resolve -x repository/heirecka + cave resolve -x hugo + ``` + +### Fedora + +Derivatives of the [Fedora] distribution of Linux include [CentOS], [Red Hat Enterprise Linux], and others. To install the extended edition of Hugo: + +```sh +sudo dnf install hugo +``` + +### Gentoo + +Derivatives of the [Gentoo] distribution of Linux include [Calculate Linux], [Funtoo], and others. To install the extended edition of Hugo: + +1. Specify the `extended` [USE] flag in /etc/portage/package.use/hugo: + + ```text + www-apps/hugo extended + ``` + +1. Build using the Portage package manager: + + ```sh + sudo emerge www-apps/hugo + ``` + +### NixOS + +The NixOS distribution of Linux includes Hugo in its package repository. To install the extended edition of Hugo: + +```sh +nix-env -iA nixos.hugo +``` + +### openSUSE + +Derivatives of the [openSUSE] distribution of Linux include [GeckoLinux], [Linux Karmada], and others. To install the extended edition of Hugo: + +```sh +sudo zypper install hugo +``` + +### Solus + +The [Solus] distribution of Linux includes Hugo in its package repository. To install the extended edition of Hugo: + +```sh +sudo eopkg install hugo +``` + +### Void Linux + +To install the extended edition of Hugo on [Void Linux]: + +```sh +sudo xbps-install -S hugo +``` + +{{% include "/_common/installation/04-build-from-source.md" %}} + +## Comparison + +||Prebuilt binaries|Package managers|Repository packages|Build from source +:--|:--:|:--:|:--:|:--: +Easy to install?|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark: +Easy to upgrade?|:heavy_check_mark:|:heavy_check_mark:|varies|:heavy_check_mark: +Easy to downgrade?|:heavy_check_mark:|:heavy_check_mark: [^1]|varies|:heavy_check_mark: +Automatic updates?|:x:|varies [^2]|:x:|:x: +Latest version available?|:heavy_check_mark:|:heavy_check_mark:|varies|:heavy_check_mark: + +[^1]: Easy if a previous version is still installed. +[^2]: Snap packages are automatically updated. Homebrew requires advanced configuration. + +[Alpine Linux]: https://alpinelinux.org/ +[Arch Linux]: https://archlinux.org/ +[Calculate Linux]: https://www.calculate-linux.org/ +[CentOS]: https://www.centos.org/ +[Debian]: https://www.debian.org/ +[elementary OS]: https://elementary.io/ +[EndeavourOS]: https://endeavouros.com/ +[Exherbo]: https://www.exherbolinux.org/ +[Fedora]: https://getfedora.org/ +[Funtoo]: https://www.funtoo.org/ +[Garuda Linux]: https://garudalinux.org/ +[GeckoLinux]: https://geckolinux.github.io/ +[Gentoo]: https://www.gentoo.org/ +[KDE neon]: https://neon.kde.org/ +[latest version]: https://github.com/gohugoio/hugo/releases/latest +[Linux Karmada]: https://linuxkamarada.com/ +[Linux Lite]: https://www.linuxliteos.com/ +[Linux Mint]: https://linuxmint.com/ +[Manjaro]: https://manjaro.org/ +[most distributions]: https://snapcraft.io/docs/installing-snapd +[MX Linux]: https://mxlinux.org/ +[openSUSE]: https://www.opensuse.org/ +[Pop!_OS]: https://pop.system76.com/ +[Red Hat Enterprise Linux]: https://www.redhat.com/ +[Snap]: https://snapcraft.io/ +[Solus]: https://getsol.us/ +[strictly confined]: https://snapcraft.io/docs/snap-confinement +[Ubuntu]: https://ubuntu.com/ +[USE]: https://packages.gentoo.org/packages/www-apps/hugo +[Void Linux]: https://voidlinux.org/ +[Zorin OS]: https://zorin.com/os/ diff --cc docs/content/en/news/_content.gotmpl index f979c9adc,000000000..af3cf47ed mode 100644,000000..100644 --- a/docs/content/en/news/_content.gotmpl +++ b/docs/content/en/news/_content.gotmpl @@@ -1,30 -1,0 +1,31 @@@ +{{/* Get releases from GitHub. */}} +{{ $u := "https://api.github.com/repos/gohugoio/hugo/releases" }} +{{ $releases := partial "helpers/funcs/get-remote-data.html" $u }} +{{ $releases = where $releases "draft" false }} +{{ $releases = where $releases "prerelease" false }} + +{{/* Add pages. */}} +{{ range $releases | first 24 }} + {{ $publishDate := .published_at | time.AsTime }} + + {{/* Correct the v0.138.0 release date. See https://github.com/gohugoio/hugo/issues/13066. */}} + {{ if eq .name "v0.138.0" }} + {{ $publishDate = "2024-11-06T11:22:34Z" }} + {{ end }} + + {{ $content := dict "mediaType" "text/markdown" "value" "" }} + {{ $dates := dict "publishDate" (time.AsTime $publishDate) }} + {{ $params := dict "permalink" .html_url }} + {{ $build := dict "render" "never" "list" "local" }} + {{ $page := dict + "build" $build + "content" $content + "dates" $dates + "kind" "page" + "params" $params - "path" .name ++ "path" (strings.Replace .name "." "-") ++ "slug" .name + "title" (printf "Release %s" .name) + }} + {{ $.AddPage $page }} +{{ end }} diff --cc docs/content/en/quick-reference/glossary/iana.md index 000000000,000000000..89497f76a new file mode 100644 --- /dev/null +++ b/docs/content/en/quick-reference/glossary/iana.md @@@ -1,0 -1,0 +1,6 @@@ ++--- ++title: IANA ++reference: https://www.iana.org/about ++--- ++ ++_IANA_ is an abbreviation for the Internet Assigned Numbers Authority, a non-profit organization that manages the allocation of global IP addresses, autonomous system numbers, DNS root zone, media types, and other Internet Protocol-related resources. diff --cc docs/content/en/quick-reference/glossary/utc.md index 000000000,000000000..a4627be5a new file mode 100644 --- /dev/null +++ b/docs/content/en/quick-reference/glossary/utc.md @@@ -1,0 -1,0 +1,6 @@@ ++--- ++title: UTC ++reference: https://en.wikipedia.org/wiki/Coordinated_Universal_Time ++--- ++ ++_UTC_ is an abbreviation for Coordinated Universal Time, the primary time standard used worldwide to regulate clocks and time. It is the basis for civil time and time zones across the globe. diff --cc docs/content/en/shortcodes/ref.md index 2f821254c,000000000..a52c2bf6e mode 100755,000000..100755 --- a/docs/content/en/shortcodes/ref.md +++ b/docs/content/en/shortcodes/ref.md @@@ -1,61 -1,0 +1,62 @@@ +--- +title: Ref shortcode +linkTitle: Ref +description: Insert a permalink to the given page reference using the ref shortcode. +categories: [] +keywords: [] +--- + +> [!note] +> To override Hugo's embedded `ref` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. + +> [!note] - > When working with the Markdown [content format], this shortcode has become largely redundant. Its functionality is now primarily handled by [link render hooks], specifically the embedded one provided by Hugo. This hook effectively addresses all the use cases previously covered by this shortcode. ++> When working with Markdown, this shortcode is obsolete. Instead, use a [link render hook] that resolves the link destination using the `GetPage` method on the `Page` object. You can either create your own, or simply enable the [embedded link render hook]. The embedded link render hook is automatically enabled for multilingual single-host projects. + +## Usage + +The `ref` shortcode accepts either a single positional argument (the path) or one or more named arguments, as listed below. + +## Arguments + +{{% include "_common/ref-and-relref-options.md" %}} + +## Examples + +The `ref` shortcode typically provides the destination for a Markdown link. + +> [!note] +> Always use [Markdown notation] notation when calling this shortcode. + +The following examples show the rendered output for a page on the English version of the site: + +```md +[Link A]({{%/* ref "/books/book-1" */%}}) + +[Link B]({{%/* ref path="/books/book-1" */%}}) + +[Link C]({{%/* ref path="/books/book-1" lang="de" */%}}) + +[Link D]({{%/* ref path="/books/book-1" lang="de" outputFormat="json" */%}}) +``` + +Rendered: + +```html +Link A + +Link B + +Link C + +Link D +``` + +## Error handling + +{{% include "_common/ref-and-relref-error-handling.md" %}} + +[content format]: /content-management/formats/ - [link render hooks]: /render-hooks/images/#default ++[embedded link render hook]: /render-hooks/links/#default ++[link render hook]: /render-hooks/links/ +[Markdown notation]: /content-management/shortcodes/#notation - [source code]: {{% eturl ref %}} ++[source code]: {{% eturl relref %}} diff --cc docs/content/en/shortcodes/relref.md index 5b413b87e,000000000..219eae81a mode 100755,000000..100755 --- a/docs/content/en/shortcodes/relref.md +++ b/docs/content/en/shortcodes/relref.md @@@ -1,61 -1,0 +1,62 @@@ +--- +title: Relref shortcode +linkTitle: Relref +description: Insert a relative permalink to the given page reference using the relref shortcode. +categories: [] +keywords: [] +--- + +> [!note] +> To override Hugo's embedded `relref` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. + +> [!note] - > When working with the Markdown [content format], this shortcode has become largely redundant. Its functionality is now primarily handled by [link render hooks], specifically the embedded one provided by Hugo. This hook effectively addresses all the use cases previously covered by this shortcode. ++> When working with Markdown, this shortcode is obsolete. Instead, use a [link render hook] that resolves the link destination using the `GetPage` method on the `Page` object. You can either create your own, or simply enable the [embedded link render hook]. The embedded link render hook is automatically enabled for multilingual single-host projects. + +## Usage + +The `relref` shortcode accepts either a single positional argument (the path) or one or more named arguments, as listed below. + +## Arguments + +{{% include "_common/ref-and-relref-options.md" %}} + +## Examples + +The `relref` shortcode typically provides the destination for a Markdown link. + +> [!note] +> Always use [Markdown notation] notation when calling this shortcode. + +The following examples show the rendered output for a page on the English version of the site: + +```md +[Link A]({{%/* ref "/books/book-1" */%}}) + +[Link B]({{%/* ref path="/books/book-1" */%}}) + +[Link C]({{%/* ref path="/books/book-1" lang="de" */%}}) + +[Link D]({{%/* ref path="/books/book-1" lang="de" outputFormat="json" */%}}) +``` + +Rendered: + +```html +Link A + +Link B + +Link C + +Link D +``` + +## Error handling + +{{% include "_common/ref-and-relref-error-handling.md" %}} + +[content format]: /content-management/formats/ - [link render hooks]: /render-hooks/links/ ++[embedded link render hook]: /render-hooks/links/#default ++[link render hook]: /render-hooks/links/ +[Markdown notation]: /content-management/shortcodes/#notation +[source code]: {{% eturl relref %}} diff --cc docs/content/en/shortcodes/vimeo.md index c354eefe0,000000000..1164ce997 mode 100755,000000..100755 --- a/docs/content/en/shortcodes/vimeo.md +++ b/docs/content/en/shortcodes/vimeo.md @@@ -1,65 -1,0 +1,73 @@@ +--- +title: Vimeo shortcode +linkTitle: Vimeo +description: Embed a Vimeo video in your content using the vimeo shortcode. +categories: [] +keywords: [] +--- + +> [!note] +> To override Hugo's embedded `vimeo` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. + +## Example + +To display a Vimeo video with this URL: + +```text +https://vimeo.com/channels/staffpicks/55073825 +``` + +Include this in your Markdown: + +```text +{{}} +``` + +Hugo renders this to: + +{{< vimeo 55073825 >}} + +## Arguments + ++id ++: (string) The video `id`. Optional if the `id` is provided as a positional argument as shown in the example above. ++ ++allowFullScreen ++: {{< new-in 0.146.0 />}} ++: (`bool`) Whether the `iframe` element can activate full screen mode. Default is `true`. ++ +class +: (`string`) The `class` attribute of the wrapping `div` element. Adding one or more CSS classes disables inline styling. + - id - : (`string`) The `id` of the Vimeo video ++loading ++: {{< new-in 0.146.0 />}} ++: (`string`) The loading attribute of the `iframe` element, either `eager` or `lazy`. Default is `eager`. + +title +: (`string`) The `title` attribute of the `iframe` element. + - If you provide a `class` or `title` you must use a named parameter for the `id`. ++Here's an example using some of the available arguments: + +```text - {{}} ++{{}} +``` + +## Privacy + +Adjust the relevant privacy settings in your site configuration. + +{{< code-toggle config=privacy.vimeo />}} + +disable +: (`bool`) Whether to disable the shortcode. Default is `false`. + +enableDNT +: (`bool`) Whether to block the Vimeo player from tracking session data and analytics. Default is `false`. + +simple +: (`bool`) Whether to enable simple mode. If `true`, the video thumbnail is fetched from Vimeo and overlaid with a play button. Clicking the thumbnail opens the video in a new Vimeo tab. Default is `false`. + +The source code for the simple version of the shortcode is available [here]. + +[here]: {{% eturl vimeo_simple %}} +[source code]: {{% eturl vimeo %}} diff --cc docs/content/en/shortcodes/youtube.md index 18c5ae6c2,000000000..ed3cf0632 mode 100755,000000..100755 --- a/docs/content/en/shortcodes/youtube.md +++ b/docs/content/en/shortcodes/youtube.md @@@ -1,91 -1,0 +1,91 @@@ +--- +title: YouTube shortcode +linkTitle: YouTube +description: Embed a YouTube video in your content using the youtube shortcode. +categories: [] +keywords: [] +--- + +> [!note] +> To override Hugo's embedded `youtube` shortcode, copy the [source code] to a file with the same name in the `layouts/shortcodes` directory. + +## Example + +To display a YouTube video with this URL: + +```text +https://www.youtube.com/watch?v=0RKpf3rK57I +``` + +Include this in your Markdown: + +```texts +{{}} +``` + +Hugo renders this to: + +{{< youtube 0RKpf3rK57I >}} + +## Arguments + +id +: (`string`) The video `id`. Optional if the `id` is provided as a positional argument as shown in the example above. + +allowFullScreen +: {{< new-in 0.125.0 />}} +: (`bool`) Whether the `iframe` element can activate full screen mode. Default is `true`. + +autoplay +: {{< new-in 0.125.0 />}} +: (`bool`) Whether to automatically play the video. Forces `mute` to `true`. Default is `false`. + +class +: (`string`) The `class` attribute of the wrapping `div` element. When specified, removes the `style` attributes from the `iframe` element and its wrapping `div` element. + +controls +: {{< new-in 0.125.0 />}} +: (`bool`) Whether to display the video controls. Default is `true`. + +end +: {{< new-in 0.125.0 />}} +: (`int`) The time, measured in seconds from the start of the video, when the player should stop playing the video. + +loading +: {{< new-in 0.125.0 />}} +: (`string`) The loading attribute of the `iframe` element, either `eager` or `lazy`. Default is `eager`. + +loop +: {{< new-in 0.125.0 />}} +: (`bool`) Whether to indefinitely repeat the video. Ignores the `start` and `end` arguments after the first play. Default is `false`. + +mute +: {{< new-in 0.125.0 />}} +: (`bool`) Whether to mute the video. Always `true` when `autoplay` is `true`. Default is `false`. + +start +: {{< new-in 0.125.0 />}} +: (`int`) The time, measured in seconds from the start of the video, when the player should start playing the video. + +title +: (`string`) The `title` attribute of the `iframe` element. Defaults to "YouTube video". + - Example using some of the above: ++Here's an example using some of the available arguments: + +```text +{{}} +``` + +## Privacy + +Adjust the relevant privacy settings in your site configuration. + +{{< code-toggle config=privacy.youTube />}} + +disable +: (`bool`) Whether to disable the shortcode. Default is `false`. + +privacyEnhanced +: (`bool`) Whether to block YouTube from storing information about visitors on your website unless the user plays the embedded video. Default is `false`. + +[source code]: {{% eturl youtube %}} diff --cc docs/content/en/templates/embedded.md index 198136393,000000000..ecfd90514 mode 100644,000000..100644 --- a/docs/content/en/templates/embedded.md +++ b/docs/content/en/templates/embedded.md @@@ -1,218 -1,0 +1,222 @@@ +--- - title: Embedded templates - description: Hugo provides embedded templates for common use cases. ++title: Embedded partial templates ++description: Hugo provides embedded partial templates for common use cases. +categories: [] +keywords: [] +weight: 170 +aliases: [/templates/internal] +--- + +## Disqus + +> [!note] +> To override Hugo's embedded Disqus template, copy the [source code]({{% eturl disqus %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> +> `{{ partial "disqus.html" . }}` + +Hugo includes an embedded template for [Disqus], a popular commenting system for both static and dynamic websites. To effectively use Disqus, secure a Disqus "shortname" by [signing up] for the free service. + +To include the embedded template: + +```go-html-template +{{ template "_internal/disqus.html" . }} +``` + +### Configuration {#configuration-disqus} + +To use Hugo's Disqus template, first set up a single configuration value: + +{{< code-toggle file=hugo >}} +[services.disqus] +shortname = 'your-disqus-shortname' +{{}} + +Hugo's Disqus template accesses this value with: + +```go-html-template +{{ .Site.Config.Services.Disqus.Shortname }} +``` + +You can also set the following in the front matter for a given piece of content: + +- `disqus_identifier` +- `disqus_title` +- `disqus_url` + +### Privacy {#privacy-disqus} + +Adjust the relevant privacy settings in your site configuration. + +{{< code-toggle config=privacy.disqus />}} + +disable +: (`bool`) Whether to disable the template. Default is `false`. + +## Google Analytics + +> [!note] +> To override Hugo's embedded Google Analytics template, copy the [source code]({{% eturl google_analytics %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> +> `{{ partial "google_analytics.html" . }}` + +Hugo includes an embedded template supporting [Google Analytics 4]. + +To include the embedded template: + +```go-html-template +{{ template "_internal/google_analytics.html" . }} +``` + +### Configuration {#configuration-google-analytics} + +Provide your tracking ID in your configuration file: + +{{< code-toggle file=hugo >}} +[services.googleAnalytics] +id = "G-MEASUREMENT_ID" +{{}} + +To use this value in your own template, access the configured ID with `{{ site.Config.Services.GoogleAnalytics.ID }}`. + +### Privacy {#privacy-google-analytics} + +Adjust the relevant privacy settings in your site configuration. + +{{< code-toggle config=privacy.googleAnalytics />}} + +disable +: (`bool`) Whether to disable the template. Default is `false`. + +respectDoNotTrack +: (`bool`) Whether to respect the browser's "do not track" setting. Default is `false`. + +## Open Graph + +> [!note] +> To override Hugo's embedded Open Graph template, copy the [source code]({{% eturl opengraph %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> +> `{{ partial "opengraph.html" . }}` + +Hugo includes an embedded template for the [Open Graph protocol](https://ogp.me/), metadata that enables a page to become a rich object in a social graph. +This format is used for Facebook and some other sites. + +To include the embedded template: + +```go-html-template +{{ template "_internal/opengraph.html" . }} +``` + +### Configuration {#configuration-open-graph} + +Hugo's Open Graph template is configured using a mix of configuration settings and [front matter](/content-management/front-matter/) on individual pages. + +{{< code-toggle file=hugo >}} +[params] + description = 'Text about my cool site' + images = ['site-feature-image.jpg'] + title = 'My cool site' + [params.social] + facebook_admin = 'jsmith' +[taxonomies] + series = 'series' +{{}} + +{{< code-toggle file=content/blog/my-post.md fm=true >}} +title = "Post title" +description = "Text about this post" +date = 2024-03-08T08:18:11-08:00 +images = ["post-cover.png"] +audio = [] +videos = [] +series = [] +tags = [] +{{}} + +Hugo uses the page title and description for the title and description metadata. +The first 6 URLs from the `images` array are used for image metadata. +If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata. + +Various optional metadata can also be set: + +- Date, published date, and last modified data are used to set the published time metadata if specified. +- `audio` and `videos` are URL arrays like `images` for the audio and video metadata tags, respectively. +- The first 6 `tags` on the page are used for the tags metadata. +- The `series` taxonomy is used to specify related "see also" pages by placing them in the same series. + +If using YouTube this will produce a og:video tag like ``. Use the `https://youtu.be/` format with YouTube videos (example: `https://youtu.be/qtIqKaDlqXo`). + ++## Pagination ++ ++See [details](/templates/pagination/). ++ +## Schema + +> [!note] +> To override Hugo's embedded Schema template, copy the [source code]({{% eturl schema %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> +> `{{ partial "schema.html" . }}` + +Hugo includes an embedded template to render [microdata] `meta` elements within the `head` element of your templates. + +To include the embedded template: + +```go-html-template +{{ template "_internal/schema.html" . }} +``` + +## X (Twitter) Cards + +> [!note] +> To override Hugo's embedded Twitter Cards template, copy the [source code]({{% eturl twitter_cards %}}) to a file with the same name in the `layouts/partials` directory, then call it from your templates using the [`partial`] function: +> +> `{{ partial "twitter_cards.html" . }}` + +Hugo includes an embedded template for [X (Twitter) Cards](https://developer.x.com/en/docs/twitter-for-websites/cards/overview/abouts-cards), +metadata used to attach rich media to Tweets linking to your site. + +To include the embedded template: + +```go-html-template +{{ template "_internal/twitter_cards.html" . }} +``` + +### Configuration {#configuration-x-cards} + +Hugo's X (Twitter) Card template is configured using a mix of configuration settings and [front-matter](/content-management/front-matter/) values on individual pages. + +{{< code-toggle file=hugo >}} +[params] + images = ["site-feature-image.jpg"] + description = "Text about my cool site" +{{}} + +{{< code-toggle file=content/blog/my-post.md fm=true >}} +title = "Post title" +description = "Text about this post" +images = ["post-cover.png"] +{{}} + +If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata. +If no image resources with those names are found, the images defined in the [site config](/configuration/) are used instead. +If no images are found at all, then an image-less Twitter `summary` card is used instead of `summary_large_image`. + +Hugo uses the page title and description for the card's title and description fields. The page summary is used if no description is given. + +Set the value of `twitter:site` in your site configuration: + +{{< code-toggle file=hugo >}} +[params.social] +twitter = "GoHugoIO" +{{}} + +NOTE: The `@` will be added for you + +```html + +``` + +[`partial`]: /functions/partials/include/ +[Disqus]: https://disqus.com +[Google Analytics 4]: https://support.google.com/analytics/answer/10089681 +[microdata]: https://html.spec.whatwg.org/multipage/microdata.html#microdata +[signing up]: https://disqus.com/profile/signup/ diff --cc docs/content/en/templates/partial.md index 8493a4674,000000000..7ff2d9594 mode 100644,000000..100644 --- a/docs/content/en/templates/partial.md +++ b/docs/content/en/templates/partial.md @@@ -1,158 -1,0 +1,158 @@@ +--- +title: Partial templates +description: Partials are smaller, context-aware components in your list and page templates that can be used economically to keep your templating DRY. +categories: [] +keywords: [] +weight: 100 +aliases: [/templates/partials/,/layout/chrome/] +--- + +{{< youtube pjS4pOLyB7c >}} + +## Use partials in your templates + +All partials for your Hugo project are located in a single `layouts/partials` directory. For better organization, you can create multiple subdirectories within `partials` as well: + +```txt +layouts/ +└── partials/ + ├── footer/ + │ ├── scripts.html + │ └── site-footer.html + ├── head/ + │ ├── favicons.html + │ ├── metadata.html + │ └── prerender.html + └── header/ + ├── site-header.html + └── site-nav.html +``` + +All partials are called within your templates using the following pattern: + +```go-html-template +{{ partial "/.html" . }} +``` + +> [!note] +> One of the most common mistakes with new Hugo users is failing to pass a context to the partial call. In the pattern above, note how "the dot" (`.`) is required as the second argument to give the partial context. You can read more about "the dot" in the [Hugo templating introduction](/templates/introduction/#context). + +> [!note] +> Do not include the word "baseof" when naming partial templates. The word "baseof" is reserved for base templates. + +As shown in the above example directory structure, you can nest your directories within `partials` for better source organization. You only need to call the nested partial's path relative to the `partials` directory: + +```go-html-template +{{ partial "header/site-header.html" . }} +{{ partial "footer/scripts.html" . }} +``` + +### Variable scoping + - The second argument in a partial call is the variable being passed down. The above examples are passing the `.`, which tells the template receiving the partial to apply the current [context][context]. ++The second argument in a partial call is the variable being passed down. The above examples are passing the dot (`.`), which tells the template receiving the partial to apply the current [context][context]. + +This means the partial will *only* be able to access those variables. The partial is isolated and cannot access the outer scope. From within the partial, `$.Var` is equivalent to `.Var`. + +## Returning a value from a partial + +In addition to outputting markup, partials can be used to return a value of any type. In order to return a value, a partial must include a lone `return` statement *at the end of the partial*. + +### Example GetFeatured + +```go-html-template +{{/* layouts/partials/GetFeatured.html */}} +{{ return first . (where site.RegularPages "Params.featured" true) }} +``` + +```go-html-template +{{/* layouts/index.html */}} +{{ range partial "GetFeatured.html" 5 }} + [...] +{{ end }} +``` + +### Example GetImage + +```go-html-template +{{/* layouts/partials/GetImage.html */}} +{{ $image := false }} +{{ with .Params.gallery }} + {{ $image = index . 0 }} +{{ end }} +{{ with .Params.image }} + {{ $image = . }} +{{ end }} +{{ return $image }} +``` + +```go-html-template +{{/* layouts/_default/single.html */}} +{{ with partial "GetImage.html" . }} + [...] +{{ end }} +``` + +> [!note] +> Only one `return` statement is allowed per partial file. + +## Inline partials + +You can also define partials inline in the template. But remember that template namespace is global, so you need to make sure that the names are unique to avoid conflicts. + +```go-html-template +Value: {{ partial "my-inline-partial.html" . }} + +{{ define "partials/my-inline-partial.html" }} +{{ $value := 32 }} +{{ return $value }} +{{ end }} +``` + +## Cached partials + +The `partialCached` template function provides significant performance gains for complex templates that don't need to be re-rendered on every invocation. See [details][partialcached]. + +## Examples + +### `header.html` + +The following `header.html` partial template is used for [spf13.com](https://spf13.com/): + +```go-html-template {file="layouts/partials/header.html"} + + + + + + {{ partial "meta.html" . }} + + + {{ .Title }} : spf13.com + + {{ if .RSSLink }}{{ end }} + + {{ partial "head_includes.html" . }} + +``` + +> [!note] +> The `header.html` example partial was built before the introduction of block templates to Hugo. Read more on [base templates and blocks](/templates/base/) for defining the outer chrome or shell of your master templates (i.e., your site's head, header, and footer). You can even combine blocks and partials for added flexibility. + +### `footer.html` + +The following `footer.html` partial template is used for [spf13.com](https://spf13.com/): + +```go-html-template {file="layouts/partials/footer.html"} +
+
+

+ © 2013-14 Steve Francia. + Some rights reserved; + please attribute properly and link back. +

+
+
+``` + +[context]: /templates/introduction/ +[partialcached]: /functions/partials/includecached/ diff --cc docs/content/en/templates/shortcode.md index 711d342cb,000000000..3ed573651 mode 100644,000000..100644 --- a/docs/content/en/templates/shortcode.md +++ b/docs/content/en/templates/shortcode.md @@@ -1,338 -1,0 +1,338 @@@ +--- +title: Shortcode templates +description: Create custom shortcodes to simplify and standardize content creation. +categories: [] +keywords: [] +weight: 120 +aliases: [/templates/shortcode-templates/] +--- + +> [!note] +> Before creating custom shortcodes, please review the [shortcodes] page in the [content management] section. Understanding the usage details will help you design and create better templates. + +## Introduction + +Hugo provides [embedded shortcodes] for many common tasks, but you'll likely need to create your own for more specific needs. Some examples of custom shortcodes you might develop include: + +- Audio players +- Video players +- Image galleries +- Diagrams +- Maps +- Tables +- And many other custom elements + +## Directory structure + +Create shortcode templates within the `layouts/shortcodes` directory, either at its root or organized into subdirectories. + +```text +layouts/ +└── shortcodes/ + ├── diagrams/ + │ ├── kroki.html + │ └── plotly.html + ├── media/ + │ ├── audio.html + │ ├── gallery.html + │ └── video.html + ├── capture.html + ├── column.html + ├── include.html + └── row.html +``` + +When calling a shortcode in a subdirectory, specify its path relative to the `shortcode` directory, excluding the file extension. + +```text +{{}} +``` + +## Lookup order + +Hugo selects shortcode templates based on the shortcode name, the current output format, and the current language. The examples below are sorted by specificity in descending order. The least specific path is at the bottom of the list. + +Shortcode name|Output format|Language|Template path +:--|:--|:--|:-- +foo|html|en|`layouts/shortcodes/foo.en.html` +foo|html|en|`layouts/shortcodes/foo.html.html` +foo|html|en|`layouts/shortcodes/foo.html` +foo|html|en|`layouts/shortcodes/foo.html.en.html` + +Shortcode name|Output format|Language|Template path +:--|:--|:--|:-- +foo|json|en|`layouts/shortcodes/foo.en.json` +foo|json|en|`layouts/shortcodes/foo.json` +foo|json|en|`layouts/shortcodes/foo.json.json` +foo|json|en|`layouts/shortcodes/foo.json.en.json` + +## Methods + +Use these methods in your shortcode templates. Refer to each methods's documentation for details and examples. + +{{% list-pages-in-section path=/methods/shortcode %}} + +## Examples + +These examples range in complexity from simple to moderately advanced, with some simplified for clarity. + +### Insert year + +Create a shortcode to insert the current year: + +```go-html-template {file="layouts/shortcodes/year.html"} +{{- now.Format "2006" -}} +``` + +Then call the shortcode from within your markup: + +```text {file="content/example.md"} +This is {{}}, and look at how far we've come. +``` + +This shortcode can be used inline or as a block on its own line. If a shortcode might be used inline, remove the surrounding [whitespace] by using [template action](g) delimiters with hyphens. + +### Insert image + +This example assumes the following content structure, where `content/example/index.md` is a [page bundle](g) containing one or more [page resources](g). + +```text +content/ +├── example/ +│ ├── a.jpg +│ └── index.md +└── _index.md +``` + +Create a shortcode to capture an image as a page resource, resize it to the given width, convert it to the WebP format, and add an `alt` attribute: + +```go-html-template {file="layouts/shortcodes/image.html"} +{{- with .Page.Resources.Get (.Get "path") }} + {{- with .Process (printf "resize %dx wepb" ($.Get "width")) -}} + {{ $.Get + {{- end }} +{{- end -}} +``` + +Then call the shortcode from within your markup: + +```text {file="content/example/index.md"} +{{}} +``` + +The example above uses: + +- The [`with`] statement to rebind the [context](g) after each successful operation +- The [`Get`] method to retrieve arguments by name +- The `$` to access the template context + +> [!note] +> Make sure that you thoroughly understand the concept of context. The most common templating errors made by new users relate to context. +> +> Read more about context in the [introduction to templating]. + +### Insert image with error handling + +The previous example, while functional, silently fails if the image is missing, and does not gracefully exit if a required argument is missing. We'll add error handling to address these issues: + +```go-html-template {file="layouts/shortcodes/image.html"} +{{- with .Get "path" }} + {{- with $r := $.Page.Resources.Get ($.Get "path") }} + {{- with $.Get "width" }} + {{- with $r.Process (printf "resize %dx wepb" ($.Get "width" )) }} + {{- $alt := or ($.Get "alt") "" -}} + {{ $alt }} + {{- end }} + {{- else }} + {{- errorf "The %q shortcode requires a 'width' argument: see %s" $.Name $.Position }} + {{- end }} + {{- else }} + {{- warnf "The %q shortcode was unable to find %s: see %s" $.Name ($.Get "path") $.Position }} + {{- end }} +{{- else }} + {{- errorf "The %q shortcode requires a 'path' argument: see %s" .Name .Position }} +{{- end -}} +``` + +This template throws an error and gracefully fails the build if the author neglected to provide a `path` or `width` argument, and it emits a warning if it cannot find the image at the specified path. If the author does not provide an `alt` argument, the `alt` attribute is set to an empty string. + +The [`Name`] and [`Position`] methods provide helpful context for errors and warnings. For example, a missing `width` argument causes the shortcode to throw this error: + +```text +ERROR The "image" shortcode requires a 'width' argument: see "/home/user/project/content/example/index.md:7:1" +``` + +### Positional arguments + +Shortcode arguments can be [named or positional]. We used named arguments previously; let's explore positional arguments. Here's the named argument version of our example: + +```text {file="content/example/index.md"} +{{}} +``` + +Here's how to call it with positional arguments: + +```text {file="content/example/index.md"} +{{}} +``` + +Using the `Get` method with zero-indexed keys, we'll initialize variables with descriptive names in our template: + +```go-html-template {file="layouts/shortcodes/image.html"} +{{ $path := .Get 0 }} +{{ $width := .Get 1 }} +{{ $alt := .Get 2 }} +``` + +> [!note] +> Positional arguments work well for frequently used shortcodes with one or two arguments. Since you'll use them often, the argument order will be easy to remember. For less frequently used shortcodes, or those with more than two arguments, named arguments improve readability and reduce the chance of errors. + +### Named and positional arguments + +You can create a shortcode that will accept both named and positional arguments, but not at the same time. Use the [`IsNamedParams`] method to determine whether the shortcode call used named or positional arguments: + +```go-html-template {file="layouts/shortcodes/image.html"} +{{ $path := cond (.IsNamedParams) (.Get "path") (.Get 0) }} +{{ $width := cond (.IsNamedParams) (.Get "width") (.Get 1) }} +{{ $alt := cond (.IsNamedParams) (.Get "alt") (.Get 2) }} +``` + +This example uses the `cond` alias for the [`compare.Conditional`] function to get the argument by name if `IsNamedParams` returns `true`, otherwise get the argument by position. + +### Argument collection + +Use the [`Params`] method to access the arguments as a collection. + +When using named arguments, the `Params` method returns a map: + +```text {file="content/example/index.md"} +{{}} +``` + +```go-html-template {file="layouts/shortcodes/image.html"} +{{ .Params.path }} → a.jpg +{{ .Params.width }} → 300 +{{ .Params.alt }} → A white kitten +``` + + When using positional arguments, the `Params` method returns a slice: + +```text {file="content/example/index.md"} +{{}} +``` + +```go-html-template {file="layouts/shortcodes/image.html"} +{{ index .Params 0 }} → a.jpg +{{ index .Params 1 }} → 300 +{{ index .Params 1 }} → A white kitten +``` + +Combine the `Params` method with the [`collections.IsSet`] function to determine if a parameter is set, even if its value is falsy. + +### Inner content + +Extract the content enclosed within shortcode tags using the [`Inner`] method. This example demonstrates how to pass both content and a title to a shortcode. The shortcode then generates a `div` element containing an `h2` element (displaying the title) and the provided content. + +```text {file="content/example.md"} +{{}} +This is a **bold** word, and this is an _emphasized_ word. +{{}} +``` + +```go-html-template {file="layouts/shortcodes/contrived.html"} +
+

{{ .Get "title" }}

+ {{ .Inner | .Page.RenderString }} +
+``` + +The preceding example called the shortcode using [standard notation], requiring us to process the inner content with the [`RenderString`] method to convert the Markdown to HTML. This conversion is unnecessary when calling a shortcode using [Markdown notation]. + +### Nesting + +The [`Parent`] method provides access to the parent shortcode context when the shortcode in question is called within the context of a parent shortcode. This provides an inheritance model. + +The following example is contrived but demonstrates the concept. Assume you have a `gallery` shortcode that expects one named `class` argument: + +```go-html-template {file="layouts/shortcodes/gallery.html"} +
+ {{ .Inner }} +
+``` + +You also have an `img` shortcode with a single named `src` argument that you want to call inside of `gallery` and other shortcodes, so that the parent defines the context of each `img`: + +```go-html-template {file="layouts/shortcodes/img.html"} +{{ $src := .Get "src" }} +{{ with .Parent }} + +{{ else }} + +{{ end }} +``` + +You can then call your shortcode in your content as follows: + +```text {file="content/example.md"} +{{}} + {{}} + {{}} +{{}} +{{}} +``` + +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 + + +``` + +### Other examples + +For guidance, consider examining Hugo's embedded shortcodes. The source code, available on [GitHub], can provide a useful model. + +## Detection + +The [`HasShortcode`] method allows you to check if a specific shortcode has been called on a page. For example, consider a custom audio shortcode: + +```text {file="content/example.md"} +{{}} +``` + +You can use the `HasShortcode` method in your base template to conditionally load CSS if the audio shortcode was used on the page: + +```go-html-template {file="layouts/_default/baseof.html"} + + ... + {{ if .HasShortcode "audio" }} + + {{ end }} + ... + +``` + +[`collections.IsSet`]: /functions/collections/isset/ +[`compare.Conditional`]: /functions/compare/conditional/ +[`Get`]: /methods/shortcode/get/ +[`HasShortcode`]: /methods/page/hasshortcode/ +[`Inner`]: /methods/shortcode/inner/ +[`IsNamedParams`]: /methods/shortcode/isnamedparams/ +[`Name`]: /methods/shortcode/name/ +[`Params`]: /methods/shortcode/params/ +[`Parent`]: /methods/shortcode/parent/ +[`Position`]: /methods/shortcode/position/ +[`RenderString`]: /methods/page/renderstring/ +[`with`]: /functions/go-template/with/ +[content management]: /content-management/shortcodes/ +[embedded shortcodes]: /shortcodes/ - [GitHub]: https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates/shortcodes ++[GitHub]: https://github.com/gohugoio/hugo/tree/master/tpl/tplimpl/embedded/templates/_shortcodes +[introduction to templating]: /templates/introduction/ +[Markdown notation]: /content-management/shortcodes/#markdown-notation +[named or positional]: /content-management/shortcodes/#arguments +[shortcodes]: /content-management/shortcodes/ +[standard notation]: /content-management/shortcodes/#standard-notation +[whitespace]: /templates/introduction/#whitespace diff --cc docs/content/en/troubleshooting/inspection.md index dc662243a,000000000..ea3c097f9 mode 100644,000000..100644 --- a/docs/content/en/troubleshooting/inspection.md +++ b/docs/content/en/troubleshooting/inspection.md @@@ -1,39 -1,0 +1,44 @@@ +--- +title: Data inspection +linkTitle: Inspection +description: Use template functions to inspect values and data structures. +categories: [] +keywords: [] +--- + +Use the [`debug.Dump`] function to inspect a data structure: + +```go-html-template +
{{ debug.Dump .Params }}
+``` + +```text +{ + "date": "2023-11-10T15:10:42-08:00", + "draft": false, + "iscjklanguage": false, + "lastmod": "2023-11-10T15:10:42-08:00", + "publishdate": "2023-11-10T15:10:42-08:00", + "tags": [ + "foo", + "bar" + ], + "title": "My first post" +} +``` + +Use the [`printf`] function (render) or [`warnf`] function (log to console) to inspect simple data structures. The layout string below displays both value and data type. + +```go-html-template +{{ $value := 42 }} +{{ printf "%[1]v (%[1]T)" $value }} → 42 (int) +``` + ++{{< new-in 0.146.0 />}} ++ ++Use the [`templates.Current`] function to visually mark template execution boundaries or to display the template call stack. ++ +[`debug.Dump`]: /functions/debug/dump/ +[`printf`]: /functions/fmt/printf/ +[`warnf`]: /functions/fmt/warnf/ ++[`templates.Current`]: /functions/templates/current/ diff --cc docs/data/embedded_template_urls.toml index f75b14f12,000000000..b2a796cd1 mode 100644,000000..100644 --- a/docs/data/embedded_template_urls.toml +++ b/docs/data/embedded_template_urls.toml @@@ -1,42 -1,0 +1,42 @@@ +# Used by the embedded template URL (eturl.html) shortcode. +# Quoted all keys because some are not valid identifiers. + +# BaseURL +'base_url' = 'https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/embedded/templates' + - # Templates - 'alias' = 'alias.html' - 'disqus' = 'disqus.html' - 'google_analytics' = 'google_analytics.html' - 'opengraph' = 'opengraph.html' - 'pagination' = 'pagination.html' - 'robots' = '_default/robots.txt' - 'rss' = '_default/rss.xml' - 'schema' = 'schema.html' - 'sitemap' = '_default/sitemap.xml' - 'sitemapindex' = '_default/sitemapindex.xml' - 'twitter_cards' = 'twitter_cards.html' ++# Partials ++'disqus' = '_partials/disqus.html' ++'google_analytics' = '_partials/google_analytics.html' ++'opengraph' = '_partials/opengraph.html' ++'pagination' = '_partials/pagination.html' ++'schema' = '_partials/schema.html' ++'twitter_cards' = '_partials/twitter_cards.html' + +# Render hooks - 'render-codeblock-goat' = '_default/_markup/render-codeblock-goat.html' - 'render-image' = '_default/_markup/render-image.html' - 'render-link' = '_default/_markup/render-link.html' - 'render-table' = '_default/_markup/render-table.html' ++'render-codeblock-goat' = '_markup/render-codeblock-goat.html' ++'render-image' = '_markup/render-image.html' ++'render-link' = '_markup/render-link.html' ++'render-table' = '_markup/render-table.html' + +# Shortcodes - 'details' = 'shortcodes/details.html' - 'figure' = 'shortcodes/figure.html' - 'gist' = 'shortcodes/gist.html' - 'highlight' = 'shortcodes/highlight.html' - 'instagram' = 'shortcodes/instagram.html' - 'param' = 'shortcodes/param.html' - 'qr' = 'shortcodes/qr.html' - 'ref' = 'shortcodes/ref.html' - 'relref' = 'shortcodes/relref.html' - 'twitter' = 'shortcodes/twitter.html' - 'twitter_simple' = 'shortcodes/twitter_simple.html' - 'vimeo' = 'shortcodes/vimeo.html' - 'vimeo_simple' = 'shortcodes/vimeo_simple.html' - 'x' = 'shortcodes/x.html' - 'x_simple' = 'shortcodes/x_simple.html' - 'youtube' = 'shortcodes/youtube.html' ++'details' = '_shortcodes/details.html' ++'figure' = '_shortcodes/figure.html' ++'gist' = '_shortcodes/gist.html' ++'highlight' = '_shortcodes/highlight.html' ++'instagram' = '_shortcodes/instagram.html' ++'param' = '_shortcodes/param.html' ++'qr' = '_shortcodes/qr.html' ++'ref' = '_shortcodes/ref.html' ++'relref' = '_shortcodes/relref.html' ++'vimeo' = '_shortcodes/vimeo.html' ++'vimeo_simple' = '_shortcodes/vimeo_simple.html' ++'x' = '_shortcodes/x.html' ++'x_simple' = '_shortcodes/x_simple.html' ++'youtube' = '_shortcodes/youtube.html' ++ ++# Other ++'alias' = 'alias.html' ++'robots' = 'robots.txt' ++'rss' = 'rss.xml' ++'sitemap' = 'sitemap.xml' ++'sitemapindex' = 'sitemapindex.xml' diff --cc docs/layouts/_markup/render-blockquote.html index 000000000,000000000..98019e12d new file mode 100644 --- /dev/null +++ b/docs/layouts/_markup/render-blockquote.html @@@ -1,0 -1,0 +1,33 @@@ ++{{- if eq .Type "alert" }} ++ {{- $alerts := dict ++ "caution" (dict "color" "red" "icon" "exclamation-triangle") ++ "important" (dict "color" "blue" "icon" "exclamation-circle") ++ "note" (dict "color" "blue" "icon" "information-circle") ++ "tip" (dict "color" "green" "icon" "light-bulb") ++ "warning" (dict "color" "orange" "icon" "exclamation-triangle") ++ }} ++ ++ {{- $alertTypes := slice }} ++ {{- range $k, $_ := $alerts }} ++ {{- $alertTypes = $alertTypes | append $k }} ++ {{- end }} ++ {{- $alertTypes = $alertTypes | sort }} ++ ++ {{- $alertType := strings.ToLower .AlertType }} ++ {{- if in $alertTypes $alertType }} ++ {{- partial "layouts/blocks/alert.html" (dict ++ "color" (or ((index $alerts $alertType).color) "blue") ++ "icon" (or ((index $alerts $alertType).icon) "information-circle") ++ "text" .Text ++ "title" .AlertTitle ++ "class" .Attributes.class ++ ) ++ }} ++ {{- else }} ++ {{- errorf `Invalid blockquote alert type. Received %s. Expected one of %s (case-insensitive). See %s.` .AlertType (delimit $alertTypes ", " ", or ") .Page.String }} ++ {{- end }} ++{{- else }} ++
++ {{ .Text }} ++
++{{- end }} diff --cc docs/layouts/_markup/render-codeblock.html index 000000000,000000000..13725ffcd new file mode 100644 --- /dev/null +++ b/docs/layouts/_markup/render-codeblock.html @@@ -1,0 -1,0 +1,98 @@@ ++{{/* prettier-ignore-start */}} ++{{/* ++Renders a highlighted code block using the given options and attributes. ++ ++In addition to the options available to the transform.Highlight function, you ++may also specify the following parameters: ++ ++@param {bool} [copy=false] Whether to display a copy-to-clipboard button. ++@param {string} [file] The file name to display above the rendered code. ++@param {bool} [details=false] Whether to wrap the highlighted code block within a details element. ++@param {bool} [open=false] Whether to initially display the content of the details element. ++@param {string} [summary=Details] The content of the details summary element rendered from Markdown to HTML. ++ ++@returns {template.HTML} ++ ++@examples ++ ++ ```go ++ fmt.Println("Hello world!") ++ ``` ++ ++ ```go {linenos=true file="layouts/index.html" copy=true} ++ fmt.Println("Hello world!") ++ ``` ++*/}} ++{{/* prettier-ignore-end */}} ++ ++{{- $copy := false }} ++{{- $file := or .Attributes.file "" }} ++{{- $details := false }} ++{{- $open := "" }} ++{{- $summary := or .Attributes.summary "Details" | .Page.RenderString }} ++{{- $ext := strings.TrimPrefix "." (path.Ext $file) }} ++{{- $lang := or .Type $ext "text" }} ++{{- if in (slice "html" "gotmpl") $lang }} ++ {{- $lang = "go-html-template" }} ++{{- end }} ++{{- if eq $lang "md" }} ++ {{- $lang = "text" }} ++{{- end }} ++ ++{{- with .Attributes.copy }} ++ {{- if in (slice true "true" 1) . }} ++ {{- $copy = true }} ++ {{- else if in (slice false "false" 0) . }} ++ {{- $copy = false }} ++ {{- end }} ++{{- end }} ++ ++{{- with .Attributes.details }} ++ {{- if in (slice true "true" 1) . }} ++ {{- $details = true }} ++ {{- else if in (slice false "false" 0) . }} ++ {{- $details = false }} ++ {{- end }} ++{{- end }} ++ ++{{- with .Attributes.open }} ++ {{- if in (slice true "true" 1) . }} ++ {{- $open = "open" }} ++ {{- else if in (slice false "false" 0) . }} ++ {{- $open = "" }} ++ {{- end }} ++{{- end }} ++ ++{{- if $details }} ++
++ {{ $summary }} ++{{- end }} ++ ++
++ {{- $fileSelectClass := "select-none" }} ++ {{- if $copy }} ++ {{- $fileSelectClass = "select-text" }} ++ ++ ++ ++ {{- end }} ++ {{- with $file }} ++
++ {{ . }} ++
++ {{- end }} ++ ++
++ {{- transform.Highlight (strings.TrimSpace .Inner) $lang .Options }} ++
++
++ ++{{- if $details }} ++
++{{- end }} diff --cc docs/layouts/_markup/render-link.html index 000000000,000000000..70011220e new file mode 100644 --- /dev/null +++ b/docs/layouts/_markup/render-link.html @@@ -1,0 -1,0 +1,320 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* Last modified: 2025-01-19T14:44:56-08:00 */}} ++ ++{{- /* ++Copyright 2025 Veriphor LLC ++ ++Licensed under the Apache License, Version 2.0 (the "License"); you may not ++use this file except in compliance with the License. You may obtain a copy of ++the License at ++ ++https://www.apache.org/licenses/LICENSE-2.0 ++ ++Unless required by applicable law or agreed to in writing, software ++distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++License for the specific language governing permissions and limitations under ++the License. ++*/}} ++ ++{{- /* ++This render hook resolves internal destinations by looking for a matching: ++ ++ 1. Content page ++ 2. Page resource (a file in the current page bundle) ++ 3. Section resource (a file in the current section) ++ 4. Global resource (a file in the assets directory) ++ ++It skips the section resource lookup if the current page is a leaf bundle. ++ ++External destinations are not modified. ++ ++You must place global resources in the assets directory. If you have placed ++your resources in the static directory, and you are unable or unwilling to move ++them, you must mount the static directory to the assets directory by including ++both of these entries in your site configuration: ++ ++ [[module.mounts]] ++ source = 'assets' ++ target = 'assets' ++ ++ [[module.mounts]] ++ source = 'static' ++ target = 'assets' ++ ++By default, if this render hook is unable to resolve a destination, including a ++fragment if present, it passes the destination through without modification. To ++emit a warning or error, set the error level in your site configuration: ++ ++ [params.render_hooks.link] ++ errorLevel = 'warning' # ignore (default), warning, or error (fails the build) ++ ++When you set the error level to warning, and you are in a development ++environment, you can visually highlight broken internal links: ++ ++ [params.render_hooks.link] ++ errorLevel = 'warning' # ignore (default), warning, or error (fails the build) ++ highlightBroken = true # true or false (default) ++ ++This will add a "broken" class to anchor elements with invalid src attributes. ++Add a rule to your CSS targeting the broken links: ++ ++ a.broken { ++ background: #ff0; ++ border: 2px solid #f00; ++ padding: 0.1em 0.2em; ++ } ++ ++This render hook may be unable to resolve destinations created with the ref and ++relref shortcodes. Unless you set the error level to ignore you should not use ++either of these shortcodes in conjunction with this render hook. ++ ++@context {string} Destination The link destination. ++@context {page} Page A reference to the page containing the link. ++@context {string} PlainText The link description as plain text. ++@context {string} Text The link description. ++@context {string} Title The link title. ++ ++@returns {template.html} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- /* Initialize. */}} ++{{- $renderHookName := "link" }} ++ ++{{- /* Verify minimum required version. */}} ++{{- $minHugoVersion := "0.141.0" }} ++{{- if lt hugo.Version $minHugoVersion }} ++ {{- errorf "The %q render hook requires Hugo v%s or later." $renderHookName $minHugoVersion }} ++{{- end }} ++ ++{{- /* Error level when unable to resolve destination: ignore, warning, or error. */}} ++{{- $errorLevel := or site.Params.render_hooks.link.errorLevel "ignore" | lower }} ++ ++{{- /* If true, adds "broken" class to broken links. Applicable in development environment when errorLevel is warning. */}} ++{{- $highlightBrokenLinks := or site.Params.render_hooks.link.highlightBroken false }} ++ ++{{- /* Validate error level. */}} ++{{- if not (in (slice "ignore" "warning" "error") $errorLevel) }} ++ {{- errorf "The %q render hook is misconfigured. The errorLevel %q is invalid. Please check your site configuration." $renderHookName $errorLevel }} ++{{- end }} ++ ++{{- /* Determine content path for warning and error messages. */}} ++{{- $contentPath := .Page.String }} ++ ++{{- /* Parse destination. */}} ++{{- $u := urls.Parse .Destination }} ++ ++{{- /* Set common message. */}} ++{{- $msg := printf "The %q render hook was unable to resolve the destination %q in %s" $renderHookName $u.String $contentPath }} ++ ++{{- /* Set attributes for anchor element. */}} ++{{- $attrs := dict "href" $u.String }} ++{{- if eq $u.String "g" }} ++ {{- /* Destination is a glossary term. */}} ++ {{- $ctx := dict ++ "contentPath" $contentPath ++ "errorLevel" $errorLevel ++ "renderHookName" $renderHookName ++ "text" .Text ++ }} ++ {{- $attrs = partial "inline/h-rh-l/get-glossary-link-attributes.html" $ctx }} ++{{- else if $u.IsAbs }} ++ {{- /* Destination is a remote resource. */}} ++ {{- $attrs = merge $attrs (dict "rel" "external") }} ++{{- else }} ++ {{- with $u.Path }} ++ {{- with $p := or ($.PageInner.GetPage .) ($.PageInner.GetPage (strings.TrimRight "/" .)) }} ++ {{- /* Destination is a page. */}} ++ {{- $href := .RelPermalink }} ++ {{- with $u.RawQuery }} ++ {{- $href = printf "%s?%s" $href . }} ++ {{- end }} ++ {{- with $u.Fragment }} ++ {{- $ctx := dict ++ "contentPath" $contentPath ++ "errorLevel" $errorLevel ++ "page" $p ++ "parsedURL" $u ++ "renderHookName" $renderHookName ++ }} ++ {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }} ++ {{- $href = printf "%s#%s" $href . }} ++ {{- end }} ++ {{- $attrs = dict "href" $href }} ++ {{- else with $.PageInner.Resources.Get $u.Path }} ++ {{- /* Destination is a page resource; drop query and fragment. */}} ++ {{- $attrs = dict "href" .RelPermalink }} ++ {{- else with (and (ne $.Page.BundleType "leaf") ($.Page.CurrentSection.Resources.Get $u.Path)) }} ++ {{- /* Destination is a section resource, and current page is not a leaf bundle. */}} ++ {{- $attrs = dict "href" .RelPermalink }} ++ {{- else with resources.Get $u.Path }} ++ {{- /* Destination is a global resource; drop query and fragment. */}} ++ {{- $attrs = dict "href" .RelPermalink }} ++ {{- else }} ++ {{- if eq $errorLevel "warning" }} ++ {{- warnf $msg }} ++ {{- if and $highlightBrokenLinks hugo.IsDevelopment }} ++ {{- $attrs = merge $attrs (dict "class" "broken") }} ++ {{- end }} ++ {{- else if eq $errorLevel "error" }} ++ {{- errorf $msg }} ++ {{- end }} ++ {{- end }} ++ {{- else }} ++ {{- with $u.Fragment }} ++ {{- /* Destination is on the same page; prepend relative permalink. */}} ++ {{- $ctx := dict ++ "contentPath" $contentPath ++ "errorLevel" $errorLevel ++ "page" $.Page ++ "parsedURL" $u ++ "renderHookName" $renderHookName ++ }} ++ {{- partial "inline/h-rh-l/validate-fragment.html" $ctx }} ++ {{- $attrs = dict "href" (printf "%s#%s" $.Page.RelPermalink .) }} ++ {{- else }} ++ {{- if eq $errorLevel "warning" }} ++ {{- warnf $msg }} ++ {{- if and $highlightBrokenLinks hugo.IsDevelopment }} ++ {{- $attrs = merge $attrs (dict "class" "broken") }} ++ {{- end }} ++ {{- else if eq $errorLevel "error" }} ++ {{- errorf $msg }} ++ {{- end }} ++ {{- end }} ++ {{- end }} ++{{- end }} ++ ++{{- /* Render anchor element. */ -}} ++{{ .Text }} ++ ++{{- define "_partials/inline/h-rh-l/validate-fragment.html" }} ++ {{- /* ++ Validates the fragment portion of a link destination. ++ ++ @context {string} contentPath The page containing the link. ++ @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error. ++ @context {page} page The page corresponding to the link destination ++ @context {struct} parsedURL The link destination parsed by urls.Parse. ++ @context {string} renderHookName The name of the render hook. ++ */}} ++ ++ {{- /* Initialize. */}} ++ {{- $contentPath := .contentPath }} ++ {{- $errorLevel := .errorLevel }} ++ {{- $p := .page }} ++ {{- $u := .parsedURL }} ++ {{- $renderHookName := .renderHookName }} ++ ++ {{- /* Validate. */}} ++ {{- with $u.Fragment }} ++ {{- if $p.Fragments.Identifiers.Contains . }} ++ {{- if gt ($p.Fragments.Identifiers.Count .) 1 }} ++ {{- $msg := printf "The %q render hook detected duplicate heading IDs %q in %s" $renderHookName . $contentPath }} ++ {{- if eq $errorLevel "warning" }} ++ {{- warnf $msg }} ++ {{- else if eq $errorLevel "error" }} ++ {{- errorf $msg }} ++ {{- end }} ++ {{- end }} ++ {{- else }} ++ {{- /* Determine target path for warning and error message. */}} ++ {{- $targetPath := "" }} ++ {{- with $p.File }} ++ {{- $targetPath = .Path }} ++ {{- else }} ++ {{- $targetPath = .Path }} ++ {{- end }} ++ {{- /* Set common message. */}} ++ {{- $msg := printf "The %q render hook was unable to find heading ID %q in %s. See %s" $renderHookName . $targetPath $contentPath }} ++ {{- if eq $targetPath $contentPath }} ++ {{- $msg = printf "The %q render hook was unable to find heading ID %q in %s" $renderHookName . $targetPath }} ++ {{- end }} ++ {{- /* Throw warning or error. */}} ++ {{- if eq $errorLevel "warning" }} ++ {{- warnf $msg }} ++ {{- else if eq $errorLevel "error" }} ++ {{- errorf $msg }} ++ {{- end }} ++ {{- end }} ++ {{- end }} ++{{- end }} ++ ++{{- define "_partials/inline/h-rh-l/get-glossary-link-attributes.html" }} ++ {{- /* ++ Returns the anchor element attributes for a link to the given glossary term. ++ ++ It first checks for the existence of a glossary page for the given term. If ++ no page is found, it then checks for a glossary page for the singular form of ++ the term. If neither page exists it throws a warning or error dependent on ++ the errorLevel setting ++ ++ The returned href attribute does not point to the glossary term page. ++ Instead, via its fragment, it points to an entry on the glossary page. ++ ++ @context {string} contentPath The page containing the link. ++ @context {string} errorLevel The error level when unable to resolve destination; ignore (default), warning, or error. ++ @context {string} renderHookName The name of the render hook. ++ @context {string} text The link text. ++ */}} ++ ++ {{- /* Get context.. */}} ++ {{- $contentPath := .contentPath }} ++ {{- $errorLevel := .errorLevel }} ++ {{- $renderHookName := .renderHookName }} ++ {{- $text := .text | transform.Plainify | strings.ToLower }} ++ ++ {{- /* Initialize. */}} ++ {{- $glossaryPath := "/quick-reference/glossary" }} ++ {{- $termGiven := $text }} ++ {{- $termActual := "" }} ++ {{- $termSingular := inflect.Singularize $termGiven }} ++ ++ {{- /* Verify that the glossary page exists. */}} ++ {{- $glossaryPage := site.GetPage $glossaryPath }} ++ {{- if not $glossaryPage }} ++ {{- errorf "The %q render hook was unable to find %s: see %s" $renderHookName $glossaryPath $contentPath }} ++ {{- end }} ++ ++ {{- /* There's a better way to handle this, but it works for now. */}} ++ {{- $cheating := dict ++ "chaining" "chain" ++ "localize" "localization" ++ "localized" "localization" ++ "paginating" "paginate" ++ "walking" "walk" ++ "ci/cd" "cicd" ++ }} ++ ++ {{- /* Verify that a glossary term page exists for the given term. */}} ++ {{- if site.GetPage (urls.JoinPath $glossaryPath ($termGiven | urlize)) }} ++ {{- $termActual = $termGiven }} ++ {{- else if site.GetPage (urls.JoinPath $glossaryPath ($termSingular | urlize)) }} ++ {{- $termActual = $termSingular }} ++ {{- else }} ++ {{- $termToTest := index $cheating $termGiven }} ++ {{- if site.GetPage (urls.JoinPath $glossaryPath ($termToTest | urlize)) }} ++ {{- $termActual = $termToTest }} ++ {{- end }} ++ {{- end }} ++ ++ {{- if not $termActual }} ++ {{- errorf "The %q render hook was unable to find a glossary page for either the singular or plural form of the term %q: see %s" $renderHookName $termGiven $contentPath }} ++ {{- end }} ++ ++ {{- /* Create the href attribute. */}} ++ {{- $href := "" }} ++ {{- if $termActual }} ++ {{- $href = fmt.Printf "%s#%s" $glossaryPage.RelPermalink (anchorize $termActual) }} ++ {{- end }} ++ ++ {{- return (dict "href" $href) }} ++{{- end -}} diff --cc docs/layouts/_markup/render-passthrough.html index 000000000,000000000..0ed001133 new file mode 100644 --- /dev/null +++ b/docs/layouts/_markup/render-passthrough.html @@@ -1,0 -1,0 +1,9 @@@ ++{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }} ++{{- with try (transform.ToMath .Inner $opts) }} ++ {{- with .Err }} ++ {{ errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }} ++ {{- else }} ++ {{- .Value }} ++ {{- $.Page.Store.Set "hasMath" true }} ++ {{- end }} ++{{- end -}} diff --cc docs/layouts/_markup/render-table.html index 000000000,000000000..7f3a88601 new file mode 100644 --- /dev/null +++ b/docs/layouts/_markup/render-table.html @@@ -1,0 -1,0 +1,31 @@@ ++
++ ++ ++ {{- range .THead }} ++ ++ {{- range . }} ++ ++ {{- end }} ++ ++ {{- end }} ++ ++ ++ {{- range .TBody }} ++ ++ {{- range . }} ++ ++ {{- end }} ++ ++ {{- end }} ++ ++
++ {{- .Text -}} ++
++ {{- .Text -}} ++
++
diff --cc docs/layouts/_partials/docs/functions-aliases.html index 000000000,000000000..b3a5a7607 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/docs/functions-aliases.html @@@ -1,0 -1,0 +1,12 @@@ ++{{- with .Params.functions_and_methods.aliases }} ++ {{- $label := "Alias" }} ++ {{- if gt (len .) 1 }} ++ {{- $label = "Aliases" }} ++ {{- end }} ++

{{ $label }}

++ {{- range . }} ++
++ {{- . -}} ++
++ {{- end }} ++{{- end -}} diff --cc docs/layouts/_partials/docs/functions-return-type.html index 000000000,000000000..75c97f8d9 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/docs/functions-return-type.html @@@ -1,0 -1,0 +1,6 @@@ ++{{- with .Params.functions_and_methods.returnType }} ++

Returns

++
++ {{- . -}} ++
++{{- end -}} diff --cc docs/layouts/_partials/docs/functions-signatures.html index 000000000,000000000..6fb61df8e new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/docs/functions-signatures.html @@@ -1,0 -1,0 +1,12 @@@ ++{{- with .Params.functions_and_methods.signatures }} ++

Syntax

++ {{- range . }} ++ {{- $signature := . }} ++ {{- if $.Params.function.returnType }} ++ {{- $signature = printf "%s ⟼ %s" . $.Params.function.returnType }} ++ {{- end }} ++
++ {{- $signature -}} ++
++ {{- end }} ++{{- end -}} diff --cc docs/layouts/_partials/helpers/debug/list-item-metadata.html index 000000000,000000000..d027484b5 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/debug/list-item-metadata.html @@@ -1,0 -1,0 +1,23 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
weight: ++ {{ .Weight }} ++
keywords: ++ {{ delimit (or .Keywords "") ", " }} ++
categories: ++ {{ delimit (or .Params.categories "") ", " }} ++
diff --cc docs/layouts/_partials/helpers/funcs/color-from-string.html index 000000000,000000000..cd599530b new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/funcs/color-from-string.html @@@ -1,0 -1,0 +1,25 @@@ ++{{ $colors := slice "slate" "green" "cyan" "blue" }} ++{{ with .single }} ++ {{ $colors = slice . }} ++{{ end }} ++ ++{{ $shades := slice 300 400 500 }} ++{{ if not .dark }} ++ {{ $shades = slice 700 800 }} ++{{ end }} ++{{ $hash := (hash.FNV32a .text) }} ++{{ $i := mod $hash (len $colors) }} ++{{ $j := mod $hash (len $shades) }} ++{{ $color := index $colors $i }} ++{{ $shade1 := index $shades $j }} ++{{ $shade2 := 0 }} ++{{ $shade3 := 0 }} ++{{ if gt $shade1 500 }} ++ {{ $shade2 = math.Min (sub $shade1 500) 100 | int }} ++ {{ $shade3 = sub $shade1 100 }} ++{{ else }} ++ {{ $shade2 = math.Max (add $shade1 500) 700 | int }} ++ {{ $shade3 = add $shade1 200 }} ++{{ end }} ++{{ $res := dict "color" $color "shade1" $shade1 "shade2" $shade2 "shade3" $shade3 }} ++{{ return $res }} diff --cc docs/layouts/_partials/helpers/funcs/get-github-info.html index 000000000,000000000..7e2dc89fa new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/funcs/get-github-info.html @@@ -1,0 -1,0 +1,28 @@@ ++{{ $url := "https://api.github.com/repos/gohugoio/hugo" }} ++{{ $cacheKey := print $url (now.Format "2006-01-02") }} ++{{ $headers := dict }} ++{{ with os.Getenv "HUGO_GH_TOKEN" }} ++ {{ $headers = dict "Authorization" (printf "Bearer %s" .) }} ++{{ end }} ++{{ $opts := dict "headers" $headers "key" $cacheKey }} ++{{ $githubRepoInfo := dict }} ++{{ with try (resources.GetRemote $url $opts) }} ++ {{ with .Err }} ++ {{ warnf "Failed to get GitHub repo info: %s" . }} ++ {{ else with (.Value | transform.Unmarshal) }} ++ {{ $githubRepoInfo = dict ++ "html_url" .html_url ++ "stargazers_url" .stargazers_url ++ "watchers_count" .watchers_count ++ "stargazers_count" .stargazers_count ++ "forks_count" .forks_count ++ "contributors_url" .contributors_url ++ "releases_url" .releases_url ++ "forks_count" .forks_count ++ }} ++ {{ else }} ++ {{ errorf "Unable to get remote resource %q" $url }} ++ {{ end }} ++{{ end }} ++ ++{{ return $githubRepoInfo }} diff --cc docs/layouts/_partials/helpers/funcs/get-remote-data.html index 000000000,000000000..ed7043421 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/funcs/get-remote-data.html @@@ -1,0 -1,0 +1,24 @@@ ++{{/* prettier-ignore-start */ -}} ++{{/* ++Parses the serialized data from the given URL and returns a map or an array. ++ ++Supports CSV, JSON, TOML, YAML, and XML. ++ ++@param {string} . The URL from which to retrieve the serialized data. ++@returns {any} ++ ++@example {{ partial "get-remote-data.html" "https://example.org/foo.json" }} ++*/}} ++{{/* prettier-ignore-end */ -}} ++{{ $url := . }} ++{{ $data := dict }} ++{{ with try (resources.GetRemote $url) }} ++ {{ with .Err }} ++ {{ errorf "%s" . }} ++ {{ else with .Value }} ++ {{ $data = .Content | transform.Unmarshal }} ++ {{ else }} ++ {{ errorf "Unable to get remote resource %q" $url }} ++ {{ end }} ++{{ end }} ++{{ return $data }} diff --cc docs/layouts/_partials/helpers/gtag.html index 000000000,000000000..59bf36ba2 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/gtag.html @@@ -1,0 -1,0 +1,27 @@@ ++{{ with site.Config.Services.GoogleAnalytics.ID }} ++ ++ ++{{ end }} diff --cc docs/layouts/_partials/helpers/linkcss.html index 000000000,000000000..814d2b52f new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/linkcss.html @@@ -1,0 -1,0 +1,28 @@@ ++{{ $r := .r }} ++{{ $attr := .attributes | default dict }} ++ ++{{ if hugo.IsDevelopment }} ++ ++{{ else }} ++ {{ with $r | minify | fingerprint }} ++ ++ {{ end }} ++{{ end }} ++ ++{{ define "render-attributes" }} ++ {{- range $k, $v := . -}} ++ {{- if $v -}} ++ {{- printf ` %s=%q` $k $v | safeHTMLAttr -}} ++ {{- else -}} ++ {{- printf ` %s` $k | safeHTMLAttr -}} ++ {{- end -}} ++ {{- end -}} ++{{ end }} diff --cc docs/layouts/_partials/helpers/linkjs.html index 000000000,000000000..00129ad38 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/linkjs.html @@@ -1,0 -1,0 +1,15 @@@ ++{{ $r := .r }} ++{{ $attr := .attributes | default dict }} ++{{ if hugo.IsDevelopment }} ++ ++{{ else }} ++ {{ with $r | fingerprint }} ++ ++ {{ end }} ++{{ end }} diff --cc docs/layouts/_partials/helpers/picture.html index 000000000,000000000..4dc16c002 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/picture.html @@@ -1,0 -1,0 +1,27 @@@ ++{{ $image := .image }} ++{{ $width := .width | default 1000 }} ++{{ $width1x := div $width 2 }} ++{{ $imageWebp := $image.Resize (printf "%dx webp" $width) }} ++{{ $image1x := $image.Resize (printf "%dx" $width1x) }} ++{{ $image1xWebp := $image.Resize (printf "%dx webp" $width1x) }} ++{{ $class := .class | default "h-64 tablet:h-96 lg:h-full w-full object-cover lg:absolute" }} ++{{ $loading := .loading | default "eager" }} ++ ++ ++ ++ ++ ++ ++ diff --cc docs/layouts/_partials/helpers/validation/validate-keywords.html index 000000000,000000000..3447ec4ef new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/helpers/validation/validate-keywords.html @@@ -1,0 -1,0 +1,22 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++We use the front matter keywords field to determine related content. To ensure ++consistency, during site build we validate each keyword against the entries in ++data/keywords.yaml. ++ ++As of March 5, 2025, this feature is experimental, pending usability ++assessment. We anticipate that the number of additions to data/keywords.yaml ++will decrease over time, though the initial implementation will require some ++effort. ++*/}} ++{{/* prettier-ignore-end */ -}} ++{{- $t := debug.Timer "validateKeywords" }} ++{{- $allowedKeywords := collections.Apply site.Data.keywords "strings.ToLower" "." }} ++{{- range $p := site.Pages }} ++ {{- range .Params.keywords }} ++ {{- if not (in $allowedKeywords (lower .)) }} ++ {{- warnf "The word or phrase %q is not in the keywords data file. See %s." . $p.Page.String }} ++ {{- end }} ++ {{- end }} ++{{- end }} ++{{- $t.Stop }} diff --cc docs/layouts/_partials/layouts/blocks/alert.html index 000000000,000000000..45f0044d9 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/blocks/alert.html @@@ -1,0 -1,0 +1,25 @@@ ++{{- $title := .title | default "" }} ++{{- $color := .color | default "yellow" }} ++{{- $icon := .icon | default "exclamation-triangle" }} ++{{- $text := .text | default "" }} ++{{- $class := .class | default "mt-6 mb-8" }} ++
++
++
++ ++ ++ ++
++
++ {{- with $title }} ++

++ {{ . }} ++

++ {{- end }} ++
++ {{ $text }} ++
++
++
++
diff --cc docs/layouts/_partials/layouts/blocks/modal.html index 000000000,000000000..7d825c06e new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/blocks/modal.html @@@ -1,0 -1,0 +1,30 @@@ ++
++
++ {{ .modal_button }} ++
++ ++
diff --cc docs/layouts/_partials/layouts/breadcrumbs.html index 000000000,000000000..69bcf7bd5 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/breadcrumbs.html @@@ -1,0 -1,0 +1,44 @@@ ++{{ $documentation := site.GetPage "/documentation" }} ++ ++ ++ ++ ++{{ define "breadcrumbs-arrow" }} ++ ++ ++ ++{{ end }} diff --cc docs/layouts/_partials/layouts/date.html index 000000000,000000000..2ec1450a5 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/date.html @@@ -1,0 -1,0 +1,5 @@@ ++{{ $humanDate := time.Format "January 2, 2006" . }} ++{{ $machineDate := time.Format "2006-01-02T15:04:05-07:00" . }} ++ diff --cc docs/layouts/_partials/layouts/docsheader.html index 000000000,000000000..7e8e950f3 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/docsheader.html @@@ -1,0 -1,0 +1,9 @@@ ++
++ {{ partial "layouts/breadcrumbs.html" . }} ++ {{ if and .IsPage (not (eq .Layout "list")) }} ++

++ {{ .Title }} ++

++ {{ end }} ++
diff --cc docs/layouts/_partials/layouts/explorer.html index 000000000,000000000..bb6f8e96a new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/explorer.html @@@ -1,0 -1,0 +1,47 @@@ ++{{/* This is currently not in use, but kept in case I change my mind. */}} ++ ++ ++{{ define "docs-explorer-section" }} ++ {{ $p := .p }} ++ {{ $level := .level }} ++ {{ $pleft := $level }} ++ {{ if gt $level 0 }} ++ {{ $pleft = add $level 1 }} ++ {{ end }} ++ {{ $pl := printf "pl-%d" $pleft }} ++ {{ $pages := $p.Sections }} ++ ++ {{ range $pages }} ++ {{ $hasChildren := gt (len .Pages) 0 }} ++ {{ $class := cond (eq $level 0) "text-primary hover:text-primary/70" "text-gray-900 dark:text-gray-400 hover:dark:text-gray-300" }} ++
  • ++ ++ {{ .LinkTitle }} ++ ++ {{ if $hasChildren }} ++
      ++ {{ template "docs-explorer-section" (dict "p" . "level" (add $level 1)) }} ++
    ++ {{ end }} ++
  • ++ {{ end }} ++ ++{{ end }} diff --cc docs/layouts/_partials/layouts/footer.html index 000000000,000000000..1b17e44e4 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/footer.html @@@ -1,0 -1,0 +1,73 @@@ ++
    ++
    ++
    ++ {{/* Column 1 */}} ++
    ++
    ++ By the ++ Hugo Authors
    ++
    ++ ++ Hugo Logo ++ ++ ++
    ++ ++ {{/* Sponsors */}} ++
    ++ {{ partial "layouts/home/sponsors.html" (dict ++ "ctx" . ++ "gtag" "footer" ++ ++ ) ++ }} ++
    ++
    ++
    ++

    ++ The Hugo logos are copyright © Steve Francia 2013–{{ now.Year }}. The ++ Hugo Gopher is based on an original work by Renée French. ++

    ++
    ++
    ++
    diff --cc docs/layouts/_partials/layouts/head/head-js.html index 000000000,000000000..d83efcd0f new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/head/head-js.html @@@ -1,0 -1,0 +1,11 @@@ ++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }} ++{{ $opts := dict "minify" true }} ++{{ with resources.Get "js/head-early.js" | js.Build $opts }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "async" "")) }} ++{{ end }} ++{{ with resources.Get "js/main.js" | js.Build $opts }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }} ++{{ end }} ++{{ with resources.Get "js/turbo.js" | js.Build $opts }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "defer" "")) }} ++{{ end }} diff --cc docs/layouts/_partials/layouts/head/head.html index 000000000,000000000..bb27f6a24 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/head/head.html @@@ -1,0 -1,0 +1,49 @@@ ++ ++{{ hugo.Generator }} ++ ++{{ if hugo.IsProduction }} ++ ++{{ else }} ++ ++{{ end }} ++ ++ ++ {{ with .Title }}{{ . }} |{{ end }} ++ {{ .Site.Title }} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{{ range .AlternativeOutputFormats -}} ++ ++{{ end -}} ++ ++ ++ ++ ++ ++ ++{{ partial "opengraph/opengraph.html" . }} ++{{- template "_internal/schema.html" . -}} ++{{- template "_internal/twitter_cards.html" . -}} ++ ++{{ if hugo.IsProduction }} ++ {{ partial "helpers/gtag.html" . }} ++{{ end }} diff --cc docs/layouts/_partials/layouts/header/githubstars.html index 000000000,000000000..75db5682a new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/header/githubstars.html @@@ -1,0 -1,0 +1,16 @@@ ++{{ with partialCached "helpers/funcs/get-github-info.html" . "-" }} ++ ++ ++ ++ ++ ++ ++ ++ {{ printf "%0.1fk" (div .stargazers_count 1000) }} ++ ++ ++{{ end }} diff --cc docs/layouts/_partials/layouts/header/header.html index 000000000,000000000..0d2e720d7 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/header/header.html @@@ -1,0 -1,0 +1,44 @@@ ++
    ++
    ++ {{ with site.Home }} ++ HUGO ++ {{ end }} ++
    ++
    ++ {{ range .Site.Menus.global }} ++ {{ .Name }} ++ {{ end }} ++ ++
    ++ ++
    ++ {{/* Search. */}} ++ {{ partial "layouts/search/input.html" . }} ++
    ++
    ++ {{/* QR code. */}} ++ {{ partial "layouts/header/qr.html" . }} ++ {{/* Theme selector. */}} ++ {{ partial "layouts/header/theme.html" . }} ++ ++ {{/* Social. */}} ++ ++
    ++
    diff --cc docs/layouts/_partials/layouts/header/qr.html index 000000000,000000000..fea64f625 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/header/qr.html @@@ -1,0 -1,0 +1,25 @@@ ++{{ $t := debug.Timer "qr" }} ++{{ $qr := partial "_inline/qr" (dict ++ "page" $ ++ "img_class" "w-10 bg-white view-transition-qr" ) ++}} ++{{ $qrBig := partial "_inline/qr" (dict "page" $ "img_class" "w-64 p-4") }} ++{{ $t.Stop }} ++ ++ ++{{ define "_partials/_inline/qr" }} ++ {{ $img_class := .img_class | default "w-10" }} ++ {{ with images.QR $.page.Permalink (dict "targetDir" "images/qr") }} ++ ++ QR code linking to {{ $.page.Permalink }} ++ {{ end }} ++{{ end }} diff --cc docs/layouts/_partials/layouts/header/theme.html index 000000000,000000000..e0b356d1d new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/header/theme.html @@@ -1,0 -1,0 +1,35 @@@ ++
    ++ ++
    diff --cc docs/layouts/_partials/layouts/home/features.html index 000000000,000000000..527c98cb1 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/home/features.html @@@ -1,0 -1,0 +1,56 @@@ ++{{/* icons source: https://heroicons.com/ */}} ++{{ $dataTOML := ` ++ [[features]] ++ heading = "Optimized for speed" ++ copy = "Written in Go, optimized for speed and designed for flexibility. With its advanced templating system and fast asset pipelines, Hugo renders a large site in seconds, often less." ++ icon = """ ++ ++ ++ """ ++ [[features]] ++ heading = "Flexible framework" ++ copy = "With its multilingual support, and powerful taxonomy system, Hugo is widely used to create documentation sites, landing pages, corporate, government, nonprofit, education, news, event, and project sites." ++ icon = """ ++ ++ ++ """ ++ [[features]] ++ heading = "Fast assets pipeline" ++ copy = "Image processing (convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data), JavaScript bundling (tree shake, code splitting), Sass processing, great TailwindCSS support." ++ icon = """ ++ ++ ++ """ ++ [[features]] ++ heading = "Embedded web server" ++ copy = "Use Hugo's embedded web server during development to instantly see changes to content, structure, behavior, and presentation. " ++ icon = """ ++ ++ ++ """ ++ ` ++}} ++{{ $data := $dataTOML | transform.Unmarshal }} ++
    ++
    ++
    ++ {{ range $data.features }} ++
    ++
    ++
    ++ {{ .icon | safeHTML }} ++
    ++ {{ .heading }} ++
    ++
    ++ {{ .copy }} ++
    ++
    ++ {{ end }} ++ ++
    ++
    ++
    diff --cc docs/layouts/_partials/layouts/home/opensource.html index 000000000,000000000..153c0f4ff new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/home/opensource.html @@@ -1,0 -1,0 +1,111 @@@ ++{{ $githubInfo := partialCached "helpers/funcs/get-github-info.html" . "-" }} ++
    ++
    ++
    ++
    ++

    ++ Open source ++

    ++

    ++ Hugo is open source and free to use. It is distributed under the ++ Apache 2.0 License. ++

    ++
    ++
    ++
    ++ ++ ++ ++ Popular. ++
    ++
    ++ Hugo has ++ {{ $githubInfo.stargazers_count | lang.FormatNumber 0 }} ++ stars on GitHub as of {{ now.Format "January 2, 2006" }}. ++ Join the crowd and hit the ++ Star button. ++
    ++
    ++
    ++
    ++ ++ ++ ++ Active. ++
    ++
    ++ Hugo has a large and active community. If you have questions or ++ need help, you can ask in the ++ Hugo forums. ++
    ++
    ++
    ++
    ++ ++ ++ ++ Frequent releases. ++
    ++
    ++ Hugo has a fast ++ release ++ cycle. The project is actively maintained and new features are ++ added regularly. ++
    ++
    ++
    ++
    ++
    ++ {{ partial "helpers/picture.html" (dict ++ "image" (resources.Get "images/hugo-github-screenshot.png") ++ "alt" "Hugo GitHub Repository" ++ "width" 640 ++ "class" "w-full max-w-[38rem] ring-1 shadow-xl dark:shadow-gray-500 ring-gray-400/10") ++ }} ++
    ++
    diff --cc docs/layouts/_partials/layouts/home/sponsors.html index 000000000,000000000..1f391e1ec new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/home/sponsors.html @@@ -1,0 -1,0 +1,44 @@@ ++{{ $gtag := .gtag | default "unknown" }} ++{{ $gtag := .gtag | default "unknown" }} ++{{ $isFooter := (eq $gtag "footer") }} ++{{ $utmSource := cond $isFooter "hugofooter" "hugohome" }} ++{{ $containerClass := .containerClass | default "mx-auto max-w-7xl px-6 lg:px-8" }} ++{{ with .ctx.Site.Data.sponsors }} ++
    ++

    Hugo Sponsors

    ++
    ++ {{ range .banners }} ++
    ++ {{ $query_params := .query_params | default "" }} ++ {{ $url := .link }} ++ {{ if not .no_query_params }} ++ {{ $url = printf "%s?%s%s" .link $query_params (querify "utm_source" (.utm_source | default $utmSource ) "utm_medium" (.utm_medium | default "banner") "utm_campaign" (.utm_campaign | default "hugosponsor") "utm_content" (.utm_content | default "gohugoio")) | safeURL }} ++ {{ end }} ++ {{ $logo := resources.Get .logo }} ++ {{ $gtagID := printf "Sponsor %s %s" .name $gtag | title }} ++ ++ ++ ++
    ++ {{ end }} ++
    ++
    ++{{ end }} diff --cc docs/layouts/_partials/layouts/hooks/body-end.html index 000000000,000000000..9ffd93ba8 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/hooks/body-end.html @@@ -1,0 -1,0 +1,3 @@@ ++{{- if .IsHome }} ++ {{- partial "helpers/validation/validate-keywords.html" }} ++{{- end }} diff --cc docs/layouts/_partials/layouts/hooks/body-main-start.html index 000000000,000000000..b28dd21c8 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/hooks/body-main-start.html @@@ -1,0 -1,0 +1,8 @@@ ++{{ if or .IsSection .IsPage }} ++ ++{{end }} diff --cc docs/layouts/_partials/layouts/hooks/body-start.html index 000000000,000000000..3430bd846 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/hooks/body-start.html @@@ -1,0 -1,0 +1,3 @@@ ++{{ with resources.Get "js/body-start.js" | js.Build (dict "minify" true) }} ++ {{ partial "helpers/linkjs.html" (dict "r" . "attributes" (dict "" "")) }} ++{{ end }} diff --cc docs/layouts/_partials/layouts/icons.html index 000000000,000000000..b05adef00 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/icons.html @@@ -1,0 -1,0 +1,70 @@@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++{{/* https://heroicons.com/mini exclamation-circle */}} ++ ++ ++ ++ ++{{/* https://heroicons.com/mini exclamation-triangle */}} ++ ++ ++ ++ ++{{/* https://heroicons.com/mini information-circle */}} ++ ++ ++ ++ ++{{/* https://heroicons.com/mini light-bulb */}} ++ ++ ++ diff --cc docs/layouts/_partials/layouts/in-this-section.html index 000000000,000000000..28e5ed7eb new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/in-this-section.html @@@ -1,0 -1,0 +1,34 @@@ ++{{- with .CurrentSection.RegularPages }} ++ {{ $hasTocOrRelated := or ($.Store.Get "hasToc") ($.Store.Get "hasRelated") }} ++
    ++

    ++ In this section ++

    ++ ++ ++
    ++{{- end }} diff --cc docs/layouts/_partials/layouts/page-edit.html index 000000000,000000000..6a976d11a new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/page-edit.html @@@ -1,0 -1,0 +1,26 @@@ ++
    ++
    ++ ++
    ++ Last updated: ++ {{ .Lastmod.Format "January 2, 2006" }}{{ with .GitInfo }} ++ : ++ {{ .Subject }} ({{ .AbbreviatedHash }}) ++ {{ end }} ++
    ++ ++ {{ with .File }} ++ {{ if not .IsContentAdapter }} ++ {{ $href := printf "%sedit/master/content/%s/%s" site.Params.ghrepo $.Lang .Path }} ++ ++ Improve this page ++ ++ {{ end }} ++ {{ end }} ++
    diff --cc docs/layouts/_partials/layouts/related.html index 000000000,000000000..0245ba771 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/related.html @@@ -1,0 -1,0 +1,22 @@@ ++{{- $heading := "See also" }} ++{{- $related := site.Pages.Related . }} ++{{- $related = $related | complement .CurrentSection.Pages | first 7 }} ++ ++{{- with $related }} ++ {{ $.Store.Set "hasRelated" true }} ++

    ++ {{ $heading }} ++

    ++ ++{{- end }} diff --cc docs/layouts/_partials/layouts/search/algolialogo.html index 000000000,000000000..a7fc6c0ae new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/search/algolialogo.html @@@ -1,0 -1,0 +1,45 @@@ ++
    ++ Search by ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
    diff --cc docs/layouts/_partials/layouts/search/button.html index 000000000,000000000..07c1f7335 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/search/button.html @@@ -1,0 -1,0 +1,22 @@@ ++{{ $textColor := "text-gray-300" }} ++{{ $fillColor := "fill-slate-400 dark:fill-slate-500" }} ++{{ if .standalone }} ++ {{ $textColor = "text-gray-800 dark:text-gray-300 " }} ++ {{ $fillColor = "fill-slate-500 dark:fill-slate-400" }} ++{{ end }} ++ ++ ++ diff --cc docs/layouts/_partials/layouts/search/input.html index 000000000,000000000..5f5ff07b9 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/search/input.html @@@ -1,0 -1,0 +1,4 @@@ ++
    ++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" false) }} ++ {{ partial "layouts/search/results.html" . }} ++
    diff --cc docs/layouts/_partials/layouts/search/results.html index 000000000,000000000..cd9b88dc0 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/search/results.html @@@ -1,0 -1,0 +1,90 @@@ ++ diff --cc docs/layouts/_partials/layouts/templates.html index 000000000,000000000..72b71a3d9 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/templates.html @@@ -1,0 -1,0 +1,7 @@@ ++ diff --cc docs/layouts/_partials/layouts/toc.html index 000000000,000000000..774bc15c7 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/layouts/toc.html @@@ -1,0 -1,0 +1,46 @@@ ++{{ with .Fragments }} ++ {{ with .Headings }} ++
    ++

    ++ On this page ++

    ++ ++
    ++ {{ end }} ++{{ end }} ++ ++{{ define "render-toc-level" }} ++ {{ range .h }} ++ {{ if and .ID (and (ge .Level 2) (le .Level 4)) }} ++ {{ $indentation := "ml-0" }} ++ {{ if eq .Level 3 }} ++ {{ $indentation = "ml-2 lg:ml-3" }} ++ {{ else if eq .Level 4 }} ++ {{ $indentation = "ml-4 lg:ml-6" }} ++ {{ end }} ++ {{ $.p.Store.Set "hasToc" true }} ++
  • ++ ++ {{ .Title | safeHTML }} ++ ++
  • ++ {{ end }} ++ {{ with .Headings }} ++
      ++ {{ template "render-toc-level" (dict "h" . "p" $.p) }} ++
    ++ {{ end }} ++ {{ end }} ++{{ end }} diff --cc docs/layouts/_partials/opengraph/get-featured-image.html index 000000000,000000000..50ee2a44d new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/opengraph/get-featured-image.html @@@ -1,0 -1,0 +1,26 @@@ ++{{ $images := $.Resources.ByType "image" }} ++{{ $featured := $images.GetMatch "*feature*" }} ++{{ if not $featured }} ++ {{ $featured = $images.GetMatch "{*cover*,*thumbnail*}" }} ++{{ end }} ++{{ if not $featured }} ++ {{ $featured = resources.Get "/opengraph/gohugoio-card-base-1.png" }} ++ {{ $size := 80 }} ++ {{ $title := $.LinkTitle }} ++ {{ if gt (len $title) 20 }} ++ {{ $size = 70 }} ++ {{ end }} ++ ++ {{ $text := $title }} ++ {{ $textOptions := dict ++ "color" "#FFF" ++ "size" $size ++ "lineSpacing" 10 ++ "x" 65 "y" 80 ++ "font" (resources.Get "/opengraph/mulish-black.ttf") ++ }} ++ ++ {{ $featured = $featured | images.Filter (images.Text $text $textOptions) }} ++{{ end }} ++ ++{{ return $featured }} diff --cc docs/layouts/_partials/opengraph/opengraph.html index 000000000,000000000..e32e07298 new file mode 100644 --- /dev/null +++ b/docs/layouts/_partials/opengraph/opengraph.html @@@ -1,0 -1,0 +1,84 @@@ ++ ++ ++ ++ ++ ++{{- with $.Params.images -}} ++ {{- range first 6 . }} ++ ++ {{ end -}} ++{{- else -}} ++ {{- $featured := partial "opengraph/get-featured-image.html" . }} ++ {{- with $featured -}} ++ ++ {{- else -}} ++ {{- with $.Site.Params.images }} ++ ++ {{ end -}} ++ {{- end -}} ++{{- end -}} ++ ++{{- if .IsPage }} ++ {{- $iso8601 := "2006-01-02T15:04:05-07:00" -}} ++ ++ {{ with .PublishDate }} ++ ++ {{ end }} ++ {{ with .Lastmod }} ++ ++ {{ end }} ++{{- end -}} ++ ++{{- with .Params.audio }}{{ end }} ++{{- with .Params.locale }} ++ ++{{ end }} ++{{- with .Site.Params.title }} ++ ++{{ end }} ++{{- with .Params.videos }} ++ {{- range . }} ++ ++ {{ end }} ++ ++{{ end }} ++ ++{{- /* If it is part of a series, link to related articles */}} ++{{- $permalink := .Permalink }} ++{{- $siteSeries := .Site.Taxonomies.series }} ++{{ with .Params.series }} ++ {{- range $name := . }} ++ {{- $series := index $siteSeries ($name | urlize) }} ++ {{- range $page := first 6 $series.Pages }} ++ {{- if ne $page.Permalink $permalink }} ++ ++ {{ end }} ++ {{- end }} ++ {{ end }} ++ ++{{ end }} ++ ++{{- /* Facebook Page Admin ID for Domain Insights */}} ++{{- with site.Params.social.facebook_admin }} ++ ++{{ end }} diff --cc docs/layouts/_shortcodes/chroma-lexers.html index 000000000,000000000..fd7130501 new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/chroma-lexers.html @@@ -1,0 -1,0 +1,28 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders an HTML template of Chroma lexers and their aliases. ++ ++@example {{< chroma-lexers >}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++
    ++ ++ ++ ++ ++ ++ ++ {{- range site.Data.docs.chroma.lexers }} ++ ++ ++ ++ ++ {{- end }} ++ ++
    LanguageIdentifiers
    {{ .Name }} ++ {{- range $k, $_ := .Aliases }} ++ {{- if $k }},{{ end }} ++ {{ . }} ++ {{- end }} ++
    ++
    diff --cc docs/layouts/_shortcodes/code-toggle.html index 000000000,000000000..a22c378be new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/code-toggle.html @@@ -1,0 -1,0 +1,120 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders syntax-highlighted configuration data in JSON, TOML, and YAML formats. ++ ++@param {string} [config] The section of site.Data.docs.config to render. ++@param {bool} [copy=false] Whether to display a copy-to-clipboard button. ++@param {string} [dataKey] The section of site.Data.docs to render. ++@param {string} [file] The file name to display above the rendered code. ++@param {bool} [fm=false] Whether to render the code as front matter. ++@param {bool} [skipHeader=false] Whether to omit top level key(s) when rendering a section of site.Data.docs.config. ++ ++@example {{< code-toggle file=hugo config=build />}} ++ ++@example {{< code-toggle file=content/example.md fm="true" }} ++ title='Example' ++ draft='false ++ {{< /code-toggle }} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- /* Initialize. */}} ++{{- $config := "" }} ++{{- $copy := false }} ++{{- $dataKey := "" }} ++{{- $file := "" }} ++{{- $fm := false }} ++{{- $skipHeader := false }} ++ ++{{- /* Get parameters. */}} ++{{- $config = .Get "config" }} ++{{- $dataKey = .Get "dataKey" }} ++{{- $file = .Get "file" }} ++{{- if in (slice "false" false 0) (.Get "copy") }} ++ {{- $copy = false }} ++{{- else if in (slice "true" true 1) (.Get "copy") }} ++ {{- $copy = true }} ++{{- end }} ++{{- if in (slice "false" false 0) (.Get "fm") }} ++ {{- $fm = false }} ++{{- else if in (slice "true" true 1) (.Get "fm") }} ++ {{- $fm = true }} ++{{- end }} ++{{- if in (slice "false" false 0) (.Get "skipHeader") }} ++ {{- $skipHeader = false }} ++{{- else if in (slice "true" true 1) (.Get "skipHeader") }} ++ {{- $skipHeader = true }} ++{{- end }} ++ ++{{- /* Define constants. */}} ++{{- $delimiters := dict "toml" "+++" "yaml" "---" }} ++{{- $langs := slice "yaml" "toml" "json" }} ++{{- $placeHolder := "#-hugo-placeholder-#" }} ++ ++{{- /* Render. */}} ++{{- $code := "" }} ++{{- if $config }} ++ {{- $file = $file | default "hugo" }} ++ {{- $sections := (split $config ".") }} ++ {{- $configSection := index $.Site.Data.docs.config $sections }} ++ {{- $code = dict $sections $configSection }} ++ {{- if $skipHeader }} ++ {{- $code = $configSection }} ++ {{- end }} ++{{- else if $dataKey }} ++ {{- $file = $file | default $dataKey }} ++ {{- $sections := (split $dataKey ".") }} ++ {{- $code = index $.Site.Data.docs $sections }} ++{{- else }} ++ {{- $code = $.Inner }} ++{{- end }} ++ ++ ++
    ++ {{- if $copy }} ++ ++ ++ ++ {{- end }} ++ ++ {{- if $code }} ++ {{- range $i, $lang := $langs }} ++
    ++ {{- $hCode := $code | transform.Remarshal . }} ++ {{- if and $fm (in (slice "toml" "yaml") .) }} ++ {{- $hCode = printf "%s\n%s\n%s" $placeHolder $hCode $placeHolder }} ++ {{- end }} ++ {{- $hCode = $hCode | replaceRE `\n+` "\n" }} ++ {{- highlight $hCode . "" | replaceRE $placeHolder (index $delimiters .) | safeHTML }} ++
    ++ {{- end }} ++ {{- end }} ++
    diff --cc docs/layouts/_shortcodes/datatable-filtered.html index 000000000,000000000..de8b0cf55 new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/datatable-filtered.html @@@ -1,0 -1,0 +1,47 @@@ ++{{ $package := (index .Params 0) }} ++{{ $listname := (index .Params 1) }} ++{{ $filter := split (index .Params 2) " " }} ++{{ $filter1 := index $filter 0 }} ++{{ $filter2 := index $filter 1 }} ++{{ $filter3 := index $filter 2 }} ++ ++{{ $list := (index (index .Site.Data.docs $package) $listname) }} ++{{ $fields := after 3 .Params }} ++{{ $list := where $list $filter1 $filter2 $filter3 }} ++ ++ ++
    ++ ++ ++ ++ {{ range $fields }} ++ ++ {{ end }} ++ ++ ++ ++ {{ range $list }} ++ ++ {{ range $k, $v := . }} ++ {{ $.Scratch.Set $k $v }} ++ {{ end }} ++ {{ range $k, $v := $fields }} ++ ++ {{ end }} ++ ++ {{ end }} ++ ++
    {{ . }}
    ++ {{ $tdContent := $.Scratch.Get . }} ++ {{ if eq $k 3 }} ++ {{ printf "%v" $tdContent | ++ strings.ReplaceRE `\[` "
    1. " | ++ strings.ReplaceRE `\s` "
    2. " | ++ strings.ReplaceRE `\]` "
    " | ++ safeHTML ++ }} ++ {{ else }} ++ {{ $tdContent }} ++ {{ end }} ++
    ++
    diff --cc docs/layouts/_shortcodes/datatable.html index 000000000,000000000..f135d841c new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/datatable.html @@@ -1,0 -1,0 +1,39 @@@ ++{{ $package := (index .Params 0) }} ++{{ $listname := (index .Params 1) }} ++{{ $list := (index (index .Site.Data.docs $package) $listname) }} ++{{ $fields := after 2 .Params }} ++ ++ ++
    ++ ++ ++ ++ {{ range $fields }} ++ {{ $s := . }} ++ {{ if eq $s "_key" }} ++ {{ $s = "type" }} ++ {{ end }} ++ ++ {{ end }} ++ ++ ++ ++ {{ range $k1, $v1 := $list }} ++ ++ {{ range $k2, $v2 := . }} ++ {{ $.Scratch.Set $k2 $v2 }} ++ {{ end }} ++ {{ range $fields }} ++ {{ $s := "" }} ++ {{ if eq . "_key" }} ++ {{ $s = $k1 }} ++ {{ else }} ++ {{ $s = $.Scratch.Get . }} ++ {{ end }} ++ ++ {{ end }} ++ ++ {{ end }} ++ ++
    {{ $s }}
    {{ $s }}
    ++
    diff --cc docs/layouts/_shortcodes/deprecated-in.html index 000000000,000000000..ce2ba389e new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/deprecated-in.html @@@ -1,0 -1,0 +1,29 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders a callout indicating the version in which a feature was deprecated. ++ ++Include descriptive text between the opening and closing tags, or omit the ++descriptive text and call the shortcode with a self-closing tag. ++ ++@param {string} 0 The semantic version string, with or without a leading v. ++ ++@example {{< deprecated-in 0.144.0 />}} ++ ++@example {{< deprecated-in 0.144.0 >}} ++ Some descriptive text here. ++ {{< /deprecated-in >}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- with $version := .Get 0 | strings.TrimLeft "vV" }} ++ {{- $href := printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }} ++ {{- $inner := strings.TrimSpace $.Inner }} ++ {{- $text := printf "Deprecated in [v%s](%s)\n\n%s" $version $href $inner | $.Page.RenderString (dict "display" "block") }} ++ {{- partial "layouts/blocks/alert.html" (dict ++ "color" "orange" ++ "icon" "exclamation" ++ "text" $text ++ ) ++ }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a single positional parameter indicating version. See %s" .Name .Position }} ++{{- end }} diff --cc docs/layouts/_shortcodes/eturl.html index 000000000,000000000..a0237dbe0 new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/eturl.html @@@ -1,0 -1,0 +1,26 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders an absolute URL to the source code for an embedded template. ++ ++Accepts either positional or named parameters, and depends on the ++embedded_templates.toml file in the data directory. ++ ++@param {string} filename The embedded template's file name, excluding extension. ++ ++@example {{% et robots.txt %}} ++@example {{% et filename=robots.txt %}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- with $filename := or (.Get "filename") (.Get 0) }} ++ {{- with site.Data.embedded_template_urls }} ++ {{- with index . $filename }} ++ {{- urls.JoinPath site.Data.embedded_template_urls.base_url . }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find a URL for the embedded template named %q. Check the name. See %s" $.Name $filename $.Position }} ++ {{- end }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find the embedded_template_urls data file in the site's data directory. See %s" $.Name $.Position }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcodes requires a named or positional parameter, the file name of the embedded template, excluding its extension. See %s" .Name .Position }} ++{{- end -}} diff --cc docs/layouts/_shortcodes/glossary-term.html index 000000000,000000000..2a45dc8cb new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/glossary-term.html @@@ -1,0 -1,0 +1,18 @@@ ++{{- /* ++Renders the definition of the given glossary term. ++ ++@param {string} (.Get 0) The glossary term. ++ ++@example {{% glossary-term float %}} ++@example {{% glossary-term "floating point" %}} ++*/ -}} ++{{- with .Get 0 }} ++ {{- $path := printf "/quick-reference/glossary/%s" (urlize .) }} ++ {{- with site.GetPage $path }} ++{{ .RenderShortcodes }}{{/* Do not indent. */}} ++ {{- else }} ++ {{- errorf "The glossary term (%s) shortcode was unable to find %s: see %s" $.Name $path $.Position }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The glossary term (%s) shortcode requires one positional parameter: see %s" $.Name $.Position }} ++{{- end -}} diff --cc docs/layouts/_shortcodes/glossary.html index 000000000,000000000..7331d5c9f new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/glossary.html @@@ -1,0 -1,0 +1,54 @@@ ++{{- /* ++Renders the glossary of terms. ++ ++When you call this shortcode using the {{% %}} notation, the glossary terms are ++Markdown headings (level 6) which means they are members of .Fragments. This ++allows the link render hook to verify links to glossary terms. ++ ++Yes, the terms themselves are pages, but we don't want to link to the pages, at ++least not right now. Instead, we want to link to the ids rendered by this ++shortcode. ++ ++@example {{% glossary %}} ++*/ -}} ++{{- $path := "/quick-reference/glossary" }} ++{{- with site.GetPage $path }} ++ ++ {{- /* Build and render alphabetical index. */}} ++ {{- $m := dict }} ++ {{- range $p := .Pages.ByTitle }} ++ {{- $k := substr .Title 0 1 | strings.ToUpper }} ++ {{- if index $m $k }} ++ {{- continue }} ++ {{- end }} ++ {{- $anchor := path.BaseName .Path | anchorize }} ++ {{- $m = merge $m (dict $k $anchor) }} ++ {{- end }} ++ {{- range $k, $v := $m }} ++[{{ $k }}](#{{ $v }}) {{/* Do not indent. */}} ++ {{- end }} ++ ++ {{/* Render glossary terms. */}} ++ {{- range $p := .Pages.ByTitle }} ++{{ .Title }}{{/* Do not indent. */}} ++: {{ .RawContent | strings.TrimSpace | safeHTML }}{{/* Do not indent. */}} ++ {{ with .Params.reference }} ++ {{- $destination := "" }} ++ {{- with $u := urls.Parse . }} ++ {{- if $u.IsAbs }} ++ {{- $destination = $u.String }} ++ {{- else }} ++ {{- with site.GetPage $u.Path }} ++ {{- $destination = .RelPermalink }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find the reference link %s: see %s" $.Name . $p.String }} ++ {{- end }} ++ {{- end }} ++ {{- end }} ++: See [details]({{ $destination }}).{{/* Do not indent. */}} ++ {{- end }} ++ {{ end }} ++ ++{{- else }} ++ {{- errorf "The %q shortcode was unable to get %s: see %s" .Name $path .Position}} ++{{- end }} diff --cc docs/layouts/_shortcodes/hl.html index 000000000,000000000..3fafcb5e8 new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/hl.html @@@ -1,0 -1,0 +1,14 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Returns syntax-highlighted code from the given text. ++ ++This is useful as a terse way to highlight inline code snippets. Calling the ++highlight shortcode for inline snippets is verbose. ++ ++@example This is {{< hl python >}}inline{{< /hl >}} code. ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- $code := .Inner | strings.TrimSpace }} ++{{- $lang := or (.Get 0) "go" }} ++{{- $opts := dict "hl_inline" true "noClasses" true }} ++{{- transform.Highlight $code $lang $opts }} diff --cc docs/layouts/_shortcodes/img.html index 000000000,000000000..e49afc57f new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/img.html @@@ -1,0 -1,0 +1,391 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders the given image using the given filter, if any. ++ ++When using the text filter, provide the arguments in this order: ++ ++0. The text ++1. The horizontal offset, in pixels, relative to the left of the image (default 20) ++2. The vertical offset, in pixels, relative to the top of the image (default 20) ++3. The font size in pixels (default 64) ++4. The line height (default 1.2) ++5. The font color (default #ffffff) ++ ++When using the padding filter, provide all arguments in this order: ++ ++0. Padding top ++1. Padding right ++2. Padding bottom ++3. Padding right ++4. Canvas color ++ ++@param {string} src The path to the image which must be a remote, page, or global resource. ++@param {string} [filter] The filter to apply to the image (case-insensitive). ++@param {string} [filterArgs] A comma-delimited list of arguments to pass to the filter. ++@param {bool} [example=false] If true, renders a before/after example. ++@param {int} [exampleWidth=384] Image width, in pixels, when rendering a before/after example. ++ ++@example {{< img src="zion-national-park.jpg" >}} ++@example {{< img src="zion-national-park.jpg" alt="Zion National Park" >}} ++ ++@example {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="grayscale" ++ >}} ++ ++@example {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="process" ++ filterArgs="resize 400x webp" ++ >}} ++ ++@example {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="colorize" ++ filterArgs="180,50,20" ++ >}} ++ ++@example {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="grayscale" ++ example=true ++ >}} ++ ++@example {{< img ++ src="zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="grayscale" ++ example=true ++ exampleWidth=400 ++ >}} ++ ++@example {{< img ++ src="images/examples/zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="Text" ++ filterArgs="Zion National Park,25,250,56" ++ example=true ++ >}} ++ ++@example {{< img ++ src="images/examples/zion-national-park.jpg" ++ alt="Zion National Park" ++ filter="Padding" ++ filterArgs="20,50,20,50,#0705" ++ example=true ++ >}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- /* Initialize. */}} ++{{- $alt := "" }} ++{{- $src := "" }} ++{{- $filter := "" }} ++{{- $filterArgs := slice }} ++{{- $example := false }} ++{{- $exampleWidth := 384 }} ++ ++{{- /* Default values to use with the text filter. */}} ++{{ $textFilterOpts := dict ++ "xOffset" 20 ++ "yOffset" 20 ++ "fontSize" 64 ++ "lineHeight" 1.2 ++ "fontColor" "#ffffff" ++ "fontPath" "https://github.com/google/fonts/raw/refs/heads/main/ofl/lato/Lato-Regular.ttf" ++}} ++ ++{{- /* Get and validate parameters. */}} ++{{- with .Get "alt" }} ++ {{- $alt = . }} ++{{- end }} ++ ++{{- with .Get "src" }} ++ {{- $src = . }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a file parameter. See %s" .Name .Position }} ++{{- end }} ++ ++{{- with .Get "filter" }} ++ {{- $filter = . | lower }} ++{{- end }} ++ ++{{- $validFilters := slice ++ "autoorient" "brightness" "colorbalance" "colorize" "contrast" "dither" ++ "gamma" "gaussianblur" "grayscale" "hue" "invert" "mask" "none" "opacity" ++ "overlay" "padding" "pixelate" "process" "saturation" "sepia" "sigmoid" "text" ++ "unsharpmask" ++}} ++ ++{{- with $filter }} ++ {{- if not (in $validFilters .) }} ++ {{- errorf "The filter passed to the %q shortcode is invalid. The filter must be one of %s. See %s" $.Name (delimit $validFilters ", " ", or ") $.Position }} ++ {{- end }} ++{{- end }} ++ ++{{- with .Get "filterArgs" }} ++ {{- $filterArgs = split . "," }} ++ {{- $filterArgs = apply $filterArgs "trim" "." " " }} ++{{- end }} ++ ++{{- if in (slice "false" false 0) (.Get "example") }} ++ {{- $example = false }} ++{{- else if in (slice "true" true 1) (.Get "example") }} ++ {{- $example = true }} ++{{- end }} ++ ++{{- with .Get "exampleWidth" }} ++ {{- $exampleWidth = . | int }} ++{{- end }} ++ ++{{- /* Get image. */}} ++{{- $ctx := dict "page" .Page "src" $src "name" .Name "position" .Position }} ++{{- $i := partial "inline/get-resource.html" $ctx }} ++ ++{{- /* Resize if rendering before/after examples. */}} ++{{- if $example }} ++ {{- $i = $i.Resize (printf "%dx" $exampleWidth) }} ++{{- end }} ++ ++{{- /* Create filter. */}} ++{{- $f := "" }} ++{{- $ctx := dict "filter" $filter "args" $filterArgs "name" .Name "position" .Position }} ++{{- if eq $filter "autoorient" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.AutoOrient }} ++{{- else if eq $filter "brightness" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Brightness (index $filterArgs 0) }} ++{{- else if eq $filter "colorbalance" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage red" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage green" "argValue" (index $filterArgs 1) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage blue" "argValue" (index $filterArgs 2) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.ColorBalance (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }} ++{{- else if eq $filter "colorize" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "hue" "argValue" (index $filterArgs 0) "min" 0 "max" 360) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "saturation" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 2) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Colorize (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }} ++{{- else if eq $filter "contrast" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Contrast (index $filterArgs 0) }} ++{{- else if eq $filter "dither" }} ++ {{- $f = images.Dither }} ++{{- else if eq $filter "gamma" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "gamma" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Gamma (index $filterArgs 0) }} ++{{- else if eq $filter "gaussianblur" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.GaussianBlur (index $filterArgs 0) }} ++{{- else if eq $filter "grayscale" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.Grayscale }} ++{{- else if eq $filter "hue" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "shift" "argValue" (index $filterArgs 0) "min" -180 "max" 180) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Hue (index $filterArgs 0) }} ++{{- else if eq $filter "invert" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 0) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.Invert }} ++{{- else if eq $filter "mask" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }} ++ {{- $maskImage := partial "inline/get-resource.html" $ctx }} ++ {{- $f = images.Mask $maskImage }} ++{{- else if eq $filter "opacity" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "opacity" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Opacity (index $filterArgs 0) }} ++{{- else if eq $filter "overlay" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $ctx := dict "src" (index $filterArgs 0) "name" .Name "position" .Position }} ++ {{- $overlayImg := partial "inline/get-resource.html" $ctx }} ++ {{- $f = images.Overlay $overlayImg (index $filterArgs 1 | float ) (index $filterArgs 2 | float) }} ++{{- else if eq $filter "padding" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 5) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.Padding ++ (index $filterArgs 0 | int) ++ (index $filterArgs 1 | int) ++ (index $filterArgs 2 | int) ++ (index $filterArgs 3 | int) ++ (index $filterArgs 4) ++ }} ++{{- else if eq $filter "pixelate" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "size" "argValue" (index $filterArgs 0) "min" 0 "max" 1000) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Pixelate (index $filterArgs 0) }} ++{{- else if eq $filter "process" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $f = images.Process (index $filterArgs 0) }} ++{{- else if eq $filter "saturation" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Saturation (index $filterArgs 0) }} ++{{- else if eq $filter "sepia" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Sepia (index $filterArgs 0) }} ++{{- else if eq $filter "sigmoid" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 2) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "midpoint" "argValue" (index $filterArgs 0) "min" 0 "max" 1) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "factor" "argValue" (index $filterArgs 1) "min" -10 "max" 10) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.Sigmoid (index $filterArgs 0) (index $filterArgs 1) }} ++{{- else if eq $filter "text" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 1) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $ctx := dict "src" $textFilterOpts.fontPath "name" .Name "position" .Position }} ++ {{- $font := or (partial "inline/get-resource.html" $ctx) }} ++ {{- $fontSize := or (index $filterArgs 3 | int) $textFilterOpts.fontSize }} ++ {{- $lineHeight := math.Max (or (index $filterArgs 4 | float) $textFilterOpts.lineHeight) 1 }} ++ {{- $opts := dict ++ "x" (or (index $filterArgs 1 | int) $textFilterOpts.xOffset) ++ "y" (or (index $filterArgs 2 | int) $textFilterOpts.yOffset) ++ "size" $fontSize ++ "linespacing" (mul (sub $lineHeight 1) $fontSize) ++ "color" (or (index $filterArgs 5) $textFilterOpts.fontColor) ++ "font" $font ++ }} ++ {{- $f = images.Text (index $filterArgs 0) $opts }} ++{{- else if eq $filter "unsharpmask" }} ++ {{- $ctx = merge $ctx (dict "argsRequired" 3) }} ++ {{- template "validate-arg-count" $ctx }} ++ {{- $filterArgs = apply $filterArgs "float" "." }} ++ {{- $ctx = merge $ctx (dict "argName" "sigma" "argValue" (index $filterArgs 0) "min" 0 "max" 500) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "amount" "argValue" (index $filterArgs 1) "min" 0 "max" 100) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $ctx = merge $ctx (dict "argName" "threshold" "argValue" (index $filterArgs 2) "min" 0 "max" 1) }} ++ {{- template "validate-arg-value" $ctx }} ++ {{- $f = images.UnsharpMask (index $filterArgs 0) (index $filterArgs 1) (index $filterArgs 2) }} ++{{- end }} ++ ++{{- /* Apply filter. */}} ++{{- $fi := $i }} ++{{- with $f }} ++ {{- $fi = $i.Filter . }} ++{{- end }} ++ ++{{- /* Render. */}} ++{{- $class := "border-1 border-gray-300 dark:border-gray-500" }} ++{{- if $example }} ++

    Original

    ++ {{ $alt }} ++

    Processed

    ++ {{ $alt }} ++{{- else -}} ++ {{ $alt }} ++{{- end }} ++ ++{{- define "validate-arg-count" }} ++ {{- $msg := "When using the %q filter, the %q shortcode requires an args parameter with %d %s. See %s" }} ++ {{- if lt (len .args) .argsRequired }} ++ {{- $text := "values" }} ++ {{- if eq 1 .argsRequired }} ++ {{- $text = "value" }} ++ {{- end }} ++ {{- errorf $msg .filter .name .argsRequired $text .position }} ++ {{- end }} ++{{- end }} ++ ++{{- define "validate-arg-value" }} ++ {{- $msg := "The %q argument passed to the %q shortcode is invalid. Expected a value in the range [%v,%v], but received %v. See %s" }} ++ {{- if or (lt .argValue .min) (gt .argValue .max) }} ++ {{- errorf $msg .argName .name .min .max .argValue .position }} ++ {{- end }} ++{{- end }} ++ ++{{- define "_partials/inline/get-resource.html" }} ++ {{- $r := "" }} ++ {{- $u := urls.Parse .src }} ++ {{- $msg := "The %q shortcode was unable to resolve %s. See %s" }} ++ {{- if $u.IsAbs }} ++ {{- with try (resources.GetRemote $u.String) }} ++ {{- with .Err }} ++ {{- errorf "%s" . }} ++ {{- else with .Value }} ++ {{- /* This is a remote resource. */}} ++ {{- $r = . }} ++ {{- else }} ++ {{- errorf $msg $.name $u.String $.position }} ++ {{- end }} ++ {{- end }} ++ {{- else }} ++ {{- with .page.Resources.Get (strings.TrimPrefix "./" $u.Path) }} ++ {{- /* This is a page resource. */}} ++ {{- $r = . }} ++ {{- else }} ++ {{- with resources.Get $u.Path }} ++ {{- /* This is a global resource. */}} ++ {{- $r = . }} ++ {{- else }} ++ {{- errorf $msg $.name $u.Path $.position }} ++ {{- end }} ++ {{- end }} ++ {{- end }} ++ {{- return $r }} ++{{- end -}} diff --cc docs/layouts/_shortcodes/imgproc.html index 000000000,000000000..fee48525a new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/imgproc.html @@@ -1,0 -1,0 +1,39 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders the given image using the given process specification. ++ ++@param {string} path The path to the image, either a page resource or a global resource. ++@param {string} spec The image processing specification. ++@param {string} alt The alt attribute of the img element. ++ ++@example {{< imgproc path="sunset.jpg" spec="resize 300x" alt="A sunset" >}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- with $.Get "path" }} ++ {{- with $i := or ($.Page.Resources.Get .) (resources.Get .) }} ++ {{- with $spec := $.Get "spec" }} ++ {{- with $i.Process . }} ++
    ++ {{ $.Get `alt` }} ++
    ++ {{- with $.Inner }} ++ {{ . }} ++ {{- else }} ++ {{ $spec }} ++ {{- end }} ++
    ++
    ++ {{- end }} ++ {{- else }} ++ {{- errorf "The %q shortcode requires a 'spec' argument containing the image processing specification. See %s" $.Name $.Position }} ++ {{- end }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a 'path' argument indicating the image path. The image must be a page resource or a global resource. See %s" $.Name $.Position }} ++{{- end }} diff --cc docs/layouts/_shortcodes/include.html index 000000000,000000000..81b0c1d8f new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/include.html @@@ -1,0 -1,0 +1,20 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders the page using the RenderShortcode method on the Page object. ++ ++You must call this shortcode using the {{% %}} notation. ++ ++@param {string} (positional parameter 0) The path to the page, relative to the content directory. ++ ++@example {{% include "functions/_common/glob-patterns" %}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- with .Get 0 }} ++ {{- with or ($.Page.GetPage .) (site.GetPage .) }} ++ {{- .RenderShortcodes }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find %q. See %s" $.Name . $.Position }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a positional parameter indicating the path of the file to include. See %s" .Name .Position }} ++{{- end }} diff --cc docs/layouts/_shortcodes/list-pages-in-section.html index 000000000,000000000..f6dfe7275 new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/list-pages-in-section.html @@@ -1,0 -1,0 +1,69 @@@ ++{{- /* ++Renders a description list of the pages in the given section. ++ ++Render a subset of the pages in the section by specifying a predefined filter, ++and whether to include those pages. ++ ++Filters are defined in the data directory, in the file named page_filters. Each ++filter is an array of paths to a file, relative to the root of the content ++directory. Hugo will throw an error if the specified filter does not exist, or ++if any of the pages in the filter do not exist. ++ ++@param {string} path The path to the section. ++@param {string} [filter=""] The name of filter list. ++@param {string} [filterType=""] The type of filter, either include or exclude. ++@param {string} [titlePrefix=""] The string to prepend to the link title. ++ ++@example {{< list-pages-in-section path=/methods/resources >}} ++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude >}} ++@example {{< list-pages-in-section path=/functions/images filter=some_filter filterType=exclude titlePrefix=foo >}} ++*/}} ++ ++{{/* Initialize. */}} ++{{ $filter := or "" (.Get "filter" | lower) }} ++{{ $filterType := or (.Get "filterType") "none" | lower }} ++{{ $filteredPages := slice }} ++{{ $titlePrefix := or (.Get "titlePrefix") "" }} ++ ++{{/* Build slice of filtered pages. */}} ++{{ with $filter }} ++ {{ with index site.Data.page_filters . }} ++ {{ range . }} ++ {{ with site.GetPage . }} ++ {{ $filteredPages = $filteredPages | append . }} ++ {{ else }} ++ {{ errorf "The %q shortcode was unable to find %q as specified in the page_filters data file. See %s" $.Name . $.Position }} ++ {{ end }} ++ {{ end }} ++ {{ else }} ++ {{ errorf "The %q shortcode was unable to find the %q filter in the page_filters data file. See %s" $.Name . $.Position }} ++ {{ end }} ++{{ end }} ++ ++{{/* Render. */}} ++{{ with $sectionPath := .Get "path" }} ++ {{ with site.GetPage . }} ++ {{ with .RegularPages }} ++ {{ range $page := .ByTitle }} ++ {{ if or ++ (and (eq $filterType "include") (in $filteredPages $page)) ++ (and (eq $filterType "exclude") (not (in $filteredPages $page))) ++ (eq $filterType "none") ++ }} ++ {{ $linkTitle := .LinkTitle }} ++ {{ with $titlePrefix }} ++ {{ $linkTitle = printf "%s%s" . $linkTitle }} ++ {{ end }} ++[{{ $linkTitle }}]({{ $page.RelPermalink }}){{/* Do not indent. */}} ++: {{ $page.Description }}{{/* Do not indent. */}} ++ {{ end }} ++ {{ end }} ++ {{ else }} ++ {{ warnf "The %q shortcode found no pages in the %q section. See %s" $.Name $sectionPath $.Position }} ++ {{ end }} ++ {{ else }} ++ {{ errorf "The %q shortcode was unable to find %q. See %s" $.Name $sectionPath $.Position }} ++ {{ end }} ++{{ else }} ++ {{ errorf "The %q shortcode requires a 'path' parameter indicating the path to the section. See %s" $.Name $.Position }} ++{{ end }} diff --cc docs/layouts/_shortcodes/module-mounts-note.html index 000000000,000000000..ba89abcbf new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/module-mounts-note.html @@@ -1,0 -1,0 +1,2 @@@ ++For a more flexible approach to configuring this directory, consult the section ++on [module mounts](/configuration/module/#mounts). diff --cc docs/layouts/_shortcodes/new-in.html index 000000000,000000000..955d0a710 new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/new-in.html @@@ -1,0 -1,0 +1,64 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders a callout or badge indicating the version in which a feature was added. ++ ++To render a callout, include descriptive text between the opening and closing ++tags. To render a badge,omit the descriptive text and call the shortcode with a ++self-closing tag. ++ ++When comparing the current version to the specified version, the "new in" ++button will be hidden if any of the following conditions is true: ++ ++- The major version difference exceeds the majorVersionDiffThreshold ++- The minor version difference exceeds the minorVersionDiffThreshold ++ ++@param {string} 0 The semantic version string, with or without a leading v. ++ ++@example {{< new-in 0.100.0 />}} ++ ++@example {{{< new-in 0.100.0 >}} ++ Some descriptive text here. ++ {{< /new-in >}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- $majorVersionDiffThreshold := 0 }} ++{{- $minorVersionDiffThreshold := 30 }} ++{{- $displayExpirationWarning := true }} ++ ++{{- with $version := .Get 0 | strings.TrimLeft "vV" }} ++ {{- $majorVersionDiff := sub (index (split hugo.Version ".") 0 | int) (index (split $version ".") 0 | int) }} ++ {{- $minorVersionDiff := sub (index (split hugo.Version ".") 1 | int) (index (split $version ".") 1 | int) }} ++ {{- if or (gt $majorVersionDiff $majorVersionDiffThreshold) (gt $minorVersionDiff $minorVersionDiffThreshold) }} ++ {{- if $displayExpirationWarning }} ++ {{- warnf "This call to the %q shortcode should be removed: %s. The button is now hidden because the specified version (%s) is older than the display threshold." $.Name $.Position $version }} ++ {{- end }} ++ {{- else }} ++ {{- $href := printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }} ++ {{- with $.Inner }} ++ {{- $inner := strings.TrimSpace . }} ++ {{- $text := printf "New in [v%s](%s)\n\n%s" $version $href $inner | $.Page.RenderString (dict "display" "block") }} ++ {{ partial "layouts/blocks/alert.html" (dict ++ "color" "green" ++ "icon" "exclamation" ++ "text" $text ++ ) ++ }} ++ {{- else }} ++ ++ ++ ++ ++ ++ New in ++ v{{ $version }} ++ ++ ++ {{- end }} ++ {{- end }} ++{{- else }} ++ {{- errorf "The %q shortcode requires a single positional parameter indicating version. See %s" .Name .Position }} ++{{- end }} diff --cc docs/layouts/_shortcodes/per-lang-config-keys.html index 000000000,000000000..31d7daf6a new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/per-lang-config-keys.html @@@ -1,0 -1,0 +1,71 @@@ ++{{/* prettier-ignore-start */ -}} ++{{- /* ++Renders a responsive grid of the configuration keys that can be defined ++separately for each language. ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- $siteConfigKeys := slice ++ (dict "baseURL" "/configuration/all/#baseurl") ++ (dict "buildDrafts" "/configuration/all/#builddrafts") ++ (dict "buildExpired" "/configuration/all/#buildexpired") ++ (dict "buildFuture" "/configuration/all/#buildfuture") ++ (dict "canonifyURLs" "/configuration/all/#canonifyurls") ++ (dict "capitalizeListTitles" "/configuration/all/#capitalizelisttitles") ++ (dict "contentDir" "/configuration/all/#contentdir") ++ (dict "copyright" "/configuration/all/#copyright") ++ (dict "disableAliases" "/configuration/all/#disablealiases") ++ (dict "disableHugoGeneratorInject" "/configuration/all/#disablehugogeneratorinject") ++ (dict "disableKinds" "/configuration/all/#disablekinds") ++ (dict "disableLiveReload" "/configuration/all/#disablelivereload") ++ (dict "disablePathToLower" "/configuration/all/#disablepathtolower") ++ (dict "enableEmoji " "/configuration/all/#enableemoji") ++ (dict "frontmatter" "/configuration/front-matter/") ++ (dict "hasCJKLanguage" "/configuration/all/#hascjklanguage") ++ (dict "languageCode" "/configuration/all/#languagecode") ++ (dict "mainSections" "/configuration/all/#mainsections") ++ (dict "markup" "/configuration/markup/") ++ (dict "mediaTypes" "/configuration/media-types/") ++ (dict "menus" "/configuration/menus/") ++ (dict "outputFormats" "/configuration/output-formats") ++ (dict "outputs" "/configuration/outputs/") ++ (dict "page" "/configuration/page/") ++ (dict "pagination" "/configuration/pagination/") ++ (dict "params" "/configuration/params/") ++ (dict "permalinks" "/configuration/permalinks/") ++ (dict "pluralizeListTitles" "/configuration/all/#pluralizelisttitles") ++ (dict "privacy" "/configuration/privacy/") ++ (dict "refLinksErrorLevel" "/configuration/all/#reflinkserrorlevel") ++ (dict "refLinksNotFoundURL" "/configuration/all/#reflinksnotfoundurl") ++ (dict "related" "/configuration/related-content/") ++ (dict "relativeURLs" "/configuration/all/#relativeurls") ++ (dict "removePathAccents" "/configuration/all/#removepathaccents") ++ (dict "renderSegments" "/configuration/all/#rendersegments") ++ (dict "sectionPagesMenu" "/configuration/all/#sectionpagesmenu") ++ (dict "security" "/configuration/security/") ++ (dict "services" "/configuration/services/") ++ (dict "sitemap" "/configuration/sitemap/") ++ (dict "staticDir" "/configuration/all/#staticdir") ++ (dict "summaryLength" "/configuration/all/#summarylength") ++ (dict "taxonomies" "/configuration/taxonomies/") ++ (dict "timeZone" "/configuration/all/#timezone") ++ (dict "title" "/configuration/all/#title") ++ (dict "titleCaseStyle" "/configuration/all/#titlecasestyle") ++}} ++ ++{{- $a := len $siteConfigKeys }} ++{{- $b := math.Ceil (div $a 2.) }} ++{{- $c := math.Ceil (div $a 3.) }} ++ ++ ++
    ++ {{- range $siteConfigKeys }} ++ {{ range $k, $v := . }} ++ {{ $u := urls.Parse $v }} ++ {{ if not (site.GetPage $u.Path) }} ++ {{ errorf "The %q shorcode was unable to find %s. See %s." $.Name $u.Path $.Position }} ++ {{ end }} ++ {{ $k }} ++ {{ end }} ++ {{- end }} ++
    diff --cc docs/layouts/_shortcodes/quick-reference.html index 000000000,000000000..0ac544036 new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/quick-reference.html @@@ -1,0 -1,0 +1,30 @@@ ++{{- /* ++Renders the child sections of the given top-level section, listing each child's ++immediate descendants. ++ ++@param {string} section The top-level section to render. ++ ++@example {{% quick-reference section="/functions" %}} ++*/ -}} ++{{ $section := "" }} ++{{ with .Get "section" }} ++ {{ $section = . }} ++{{ else }} ++ {{ errorf "The %q shortcode requires a 'section' parameter. See %s" .Name .Position }} ++{{ end }} ++ ++{{ with site.GetPage $section }} ++ {{ range .Sections }} ++## {{ .LinkTitle }}{{/* Do not indent. */}} ++{{ .Description }}{{/* Do not indent. */}} ++ {{ .Content }} ++ {{ with .Pages }} ++ {{ range . }} ++[{{ .LinkTitle }}]({{ .RelPermalink }}){{/* Do not indent. */}} ++: {{ .Description }}{{/* Do not indent. */}} ++ {{ end }} ++ {{ end }} ++ {{ end }} ++{{ else }} ++ {{ errorf "The %q shortcodes was unable to find the %q section. See %s" .Name $section .Position }} ++{{ end }} diff --cc docs/layouts/_shortcodes/root-configuration-keys.html index 000000000,000000000..46a6e074f new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/root-configuration-keys.html @@@ -1,0 -1,0 +1,45 @@@ ++{{/* prettier-ignore-start */ -}} ++{{/* ++Renders a comma-separated list of links to the root key configuration pages. ++ ++@example {{< root-configuration-keys >}} ++*/ -}} ++{{/* prettier-ignore-end */ -}} ++{{- /* Create scratch map of key:filename. */}} ++{{- $s := newScratch }} ++{{- range $k, $v := site.Data.docs.config }} ++ {{- if or (reflect.IsMap .) (reflect.IsSlice .) }} ++ {{- $s.Set $k ($k | humanize | anchorize) }} ++ {{- end }} ++{{- end }} ++ ++{{/* Deprecated. */}} ++{{- $s.Delete "author" }} ++ ++{{/* Use mounts instead. */}} ++{{- $s.Delete "staticDir" }} ++{{- $s.Delete "ignoreFiles" }} ++ ++{{/* This key is "HTTPCache" not "httpCache". */}} ++{{- $s.Set "HTTPCache" "http-cache" }} ++ ++{{/* This key is "frontmatter" not "frontMatter" */}} ++{{- $s.Set "frontmatter" "front-matter" }} ++ ++{{/* The page title is "Related content" not "related". */}} ++{{- $s.Set "related" "related-content" }} ++ ++{{/* It can be configured as bool or map; we want to show map. */}} ++{{- $s.Set "uglyURLs" "ugly-urls" }} ++ ++{{- $links := slice }} ++{{- range $k, $v := $s.Values }} ++ {{- $path := printf "/configuration/%s" $v }} ++ {{- with site.GetPage $path }} ++ {{- $links = $links | append (printf "%s" .RelPermalink $k) }} ++ {{- else }} ++ {{- errorf "The %q shortcode was unable to find the page %s. See %s." $.Name $path $.Position }} ++ {{- end }} ++{{- end }} ++ ++{{- delimit $links ", " ", and " | safeHTML -}} diff --cc docs/layouts/_shortcodes/syntax-highlighting-styles.html index 000000000,000000000..297849cef new file mode 100644 --- /dev/null +++ b/docs/layouts/_shortcodes/syntax-highlighting-styles.html @@@ -1,0 -1,0 +1,70 @@@ ++{{- /* ++Renders a gallery a Chroma syntax highlighting styles. ++ ++@example {{% syntax-highlighting-styles %}} ++*/ -}} ++{{- $examples := slice }} ++ ++{{- /* Example: css */}} ++{{- $example := dict "lang" "css" "code" ` ++body { ++ font-size: 16px; /* comment */ ++} ++`}} ++{{- $examples = $examples | append $example }} ++ ++{{- /* Example: html */}} ++{{- $example = dict "lang" "html" "code" ` ++Example ++`}} ++{{- $examples = $examples | append $example }} ++ ++{{- /* Example: go-html-template */}} ++{{- $example = dict "lang" "go-html-template" "code" ` ++{{ with $.Page.Params.content }} ++ {{ . | $.Page.RenderString }} {{/* comment */}} ++{{ end }} ++`}} ++{{- $examples = $examples | append $example }} ++ ++{{- /* Example: javascript */}} ++{{- $example = dict "lang" "javascript" "code" ` ++if ([1,"one",2,"two"].includes(value)){ ++ console.log("Number is either 1 or 2."); // comment ++} ++`}} ++{{- $examples := $examples | append $example }} ++ ++{{- /* Example: markdown */}} ++{{- $example = dict "lang" "markdown" "code" ` ++{{< figure src="kitten.jpg" >}} ++[example](https://example.org "An example") ++`}} ++{{- $examples := $examples | append $example }} ++ ++{{- /* Example: toml */}} ++{{- $example = dict "lang" "toml" "code" ` ++[params] ++bool = true # comment ++string = 'foo' ++`}} ++{{- $examples := $examples | append $example }} ++ ++{{- /* Render */}} ++{{- with site.Data.docs.chroma.styles }} ++ {{- range $style := . }} ++ ++### {{ $style }} {class="!mt-7 !mb-6"}{{/* Do not indent. */}} ++ ++ {{- range $examples }} ++ ++{{ .lang }}{{/* Do not indent. */}} ++{class="text-sm !-mt-3 !-mb-5"}{{/* Do not indent. */}} ++ ++```{{ .lang }} {noClasses=true style="{{ $style }}"}{{/* Do not indent. */}} ++{{- .code | safeHTML -}}{{/* Do not indent. */}} ++```{{/* Do not indent. */}} ++ ++ {{- end }} ++ {{- end }} ++{{- end }} diff --cc docs/layouts/baseof.html index 000000000,000000000..4c14a6b6d new file mode 100644 --- /dev/null +++ b/docs/layouts/baseof.html @@@ -1,0 -1,0 +1,74 @@@ ++ ++ ++ ++ ++ ++ {{ .Title }} ++ ++ ++ ++ {{ partial "layouts/head/head-js.html" . }} ++ {{ with (templates.Defer (dict "key" "global")) }} ++ {{ $t := debug.Timer "tailwindcss" }} ++ {{ with resources.Get "css/styles.css" }} ++ {{ $opts := dict ++ "inlineImports" true ++ "minify" (not hugo.IsDevelopment) ++ }} ++ {{ with . | css.TailwindCSS $opts }} ++ {{ partial "helpers/linkcss.html" (dict "r" .) }} ++ {{ end }} ++ {{ end }} ++ {{ $t.Stop }} ++ {{ end }} ++ {{ $noop := .WordCount }} ++ {{ if .Page.Store.Get "hasMath" }} ++ ++ {{ end }} ++ {{ partial "layouts/head/head.html" . }} ++ ++ ++ {{ partial "layouts/hooks/body-start.html" . }} ++ {{/* Layout. */}} ++ {{ block "header" . }} ++ {{ partial "layouts/header/header.html" . }} ++ {{ end }} ++ {{ block "subheader" . }} ++ {{ end }} ++ {{ block "hero" . }} ++ {{ end }} ++
    ++
    ++ {{ partial "layouts/hooks/body-main-start.html" . }} ++ {{ block "main" . }}{{ end }} ++
    ++ {{ block "rightsidebar" . }} ++ ++ {{ end }} ++
    ++ {{/* Common icons. */}} ++ {{ partial "layouts/icons.html" . }} ++ {{/* Common templates. */}} ++ {{ partial "layouts/templates.html" . }} ++ {{/* Footer. */}} ++ {{ block "footer" . }} ++ {{ partial "layouts/footer.html" . }} ++ {{ end }} ++ {{ partial "layouts/hooks/body-end.html" . }} ++ ++ diff --cc docs/layouts/home.headers index 000000000,000000000..1216e42d4 new file mode 100644 --- /dev/null +++ b/docs/layouts/home.headers @@@ -1,0 -1,0 +1,5 @@@ ++/* ++ X-Frame-Options: DENY ++ X-XSS-Protection: 1; mode=block ++ X-Content-Type-Options: nosniff ++ Referrer-Policy: origin-when-cross-origin diff --cc docs/layouts/home.html index 000000000,000000000..392f66cd8 new file mode 100644 --- /dev/null +++ b/docs/layouts/home.html @@@ -1,0 -1,0 +1,52 @@@ ++{{ define "main" }} ++
    ++ {{ partial "layouts/home/opensource.html" . }} ++
    ++ {{ partial "layouts/home/sponsors.html" (dict "ctx" . "gtag" "home" ) }} ++
    ++ {{ partial "layouts/home/features.html" . }} ++
    ++{{ end }} ++ ++{{ define "hero" }} ++
    ++
    ++
    ++ Hugo Logo ++

    ++ The world’s fastest framework for building websites ++

    ++
    ++ Hugo is one of the most popular open-source static site generators. ++ With its amazing speed and flexibility, Hugo makes building websites ++ fun again. ++
    ++
    ++ {{ with site.GetPage "/getting-started" }} ++ {{ .LinkTitle }} ++ {{ end }} ++
    ++ {{ partial "layouts/search/button.html" (dict "page" . "standalone" true) }} ++
    ++
    ++
    ++
    ++
    ++{{ end }} ++ ++{{ define "rightsidebar" }} ++ {{ printf "%c" '\u00A0' }} ++{{ end }} ++ ++{{ define "leftsidebar" }} ++ {{ printf "%c" '\u00A0' }} ++{{ end }} diff --cc docs/layouts/home.redir index 000000000,000000000..bb72f96e5 new file mode 100644 --- /dev/null +++ b/docs/layouts/home.redir @@@ -1,0 -1,0 +1,6 @@@ ++# Netlify redirects. See https://www.netlify.com/docs/redirects/ ++{{ range $p := .Site.Pages -}} ++{{ range .Aliases }} ++{{ . | printf "%-35s" }} {{ $p.RelPermalink -}} ++{{ end -}} ++{{- end -}} diff --cc docs/layouts/list.html index 000000000,000000000..b049b6da9 new file mode 100644 --- /dev/null +++ b/docs/layouts/list.html @@@ -1,0 -1,0 +1,69 @@@ ++{{ define "main" }} ++ {{ $pages := "" }} ++ {{ if .IsPage }} ++ {{/* We currently have a slightly odd content structure with no top level /docs section. */}} ++ {{ $pages = .CurrentSection.Pages }} ++ {{ else }} ++ {{ $pages = .Pages }} ++ {{ if eq .Section "news" }} ++ {{ $pages = $pages.ByPublishDate.Reverse }} ++ {{ end }} ++ {{ end }} ++ ++ ++
    ++ {{ partial "layouts/docsheader.html" . }} ++ ++
    ++{{ end }} ++ ++{{ define "rightsidebar" }} ++ {{ printf "%c" '\u00A0' }} ++{{ end }} diff --cc docs/layouts/list.rss.xml index 000000000,000000000..90fa22148 new file mode 100644 --- /dev/null +++ b/docs/layouts/list.rss.xml @@@ -1,0 -1,0 +1,33 @@@ ++{{- printf "" | safeHTML }} ++ ++ ++ Hugo News ++ Recent news about Hugo, a static site generator written in Go, optimized for speed and designed for flexibility. ++ {{ .Permalink }} ++ Hugo {{ hugo.Version }} ++ {{ or site.Language.LanguageCode site.Language.Lang }} ++ {{- with site.Copyright }} ++ {{ . }} ++ {{- end }} ++ {{- with .OutputFormats.Get "rss" }} ++ {{ printf "" .Permalink .MediaType | safeHTML }} ++ {{- end }} ++ {{- $limit := cond (gt site.Config.Services.RSS.Limit 0) site.Config.Services.RSS.Limit 999 }} ++ {{- $pages := "" }} ++ {{- with site.GetPage "/news" }} ++ {{- $pages = .Pages.ByPublishDate.Reverse | first $limit }} ++ {{- else }} ++ {{- errorf "The list.rss.xml layout was unable to find the 'news' page." }} ++ {{- end }} ++ {{ (index $pages 0).PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }} ++ {{- range $pages }} ++ ++ {{ .Title }} ++ {{ or .Params.permalink .Permalink }} ++ {{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }} ++ {{ or .Params.permalink .Permalink }} ++ {{ .Summary | transform.XMLEscape | safeHTML }} ++ ++ {{- end }} ++ ++ diff --cc docs/layouts/single.html index 000000000,000000000..2e9e4f379 new file mode 100644 --- /dev/null +++ b/docs/layouts/single.html @@@ -1,0 -1,0 +1,80 @@@ ++{{ define "main" }} ++ {{ $ttop := debug.Timer "single" }} ++
    ++ {{ partial "layouts/docsheader.html" . }} ++
    ++ {{ with .Params.description }} ++
    ++ {{ . | markdownify }} ++
    ++ {{ end }} ++ {{ if .Params.show_publish_date }} ++ {{ with .PublishDate }} ++

    ++ {{ partial "layouts/date.html" . }} ++

    ++ {{ end }} ++ {{ end }} ++ {{ $t := debug.Timer "single.categories" }} ++ {{ $categories := .GetTerms "categories" }} ++ {{ with $categories }} ++
    ++ {{ range . }} ++ {{ $text := .LinkTitle }} ++ {{ $class := "" }} ++ {{ range (slice true false ) }} ++ {{ $color := partial "helpers/funcs/color-from-string.html" (dict "text" $text "dark" . "--single" "green" ) }} ++ ++ {{ $prefix := "" }} ++ {{ if . }} ++ {{ $prefix = "dark:" }} ++ {{ end }} ++ {{ $class = printf "%sbg-%s-%d %stext-%s-%d border %sborder-%s-%d" ++ $prefix $color.color $color.shade1 ++ $prefix $color.color $color.shade2 ++ $prefix $color.color $color.shade3 ++ }} ++ {{ end }} ++ ++ ++ ++ {{ .LinkTitle }} ++ ++ {{ end }} ++
    ++ {{ end }} ++ {{ $t.Stop }} ++ ++ {{ if .Params.functions_and_methods.signatures }} ++
    ++ {{- partial "docs/functions-signatures.html" . -}} ++ {{- partial "docs/functions-return-type.html" . -}} ++ {{- partial "docs/functions-aliases.html" . -}} ++
    ++ {{ end }} ++ {{ $t := debug.Timer "single.content" }} ++ {{ .Content }} ++ {{ $t.Stop }} ++ {{ $t := debug.Timer "single.page-edit" }} ++ {{ partial "layouts/page-edit.html" . }} ++ {{ $t.Stop }} ++
    ++
    ++ {{ $ttop.Stop }} ++{{ end }} ++ ++{{ define "rightsidebar_content" }} ++ {{/* in-this-section.html depends on these being reneredc first. */}} ++ {{ $related := partial "layouts/related.html" . }} ++ {{ $toc := partial "layouts/toc.html" . }} ++ {{ if not .Params.hide_in_this_section }} ++ {{ partial "layouts/in-this-section.html" . }} ++ {{ end }} ++ {{ $related }} ++ {{ if $.Store.Get "hasToc" }} ++ {{ $toc }} ++ {{ end }} ++{{ end }} diff --cc docs/netlify.toml index 67c146cad,000000000..c24a32a60 mode 100644,000000..100644 --- a/docs/netlify.toml +++ b/docs/netlify.toml @@@ -1,55 -1,0 +1,55 @@@ +[build] + publish = "public" + command = "hugo --gc --minify" + + [build.environment] - HUGO_VERSION = "0.145.0" ++ HUGO_VERSION = "0.146.7" + +[context.production.environment] + HUGO_ENV = "production" + HUGO_ENABLEGITINFO = "true" + +[context.split1] + command = "hugo --gc --minify --enableGitInfo" + + [context.split1.environment] + HUGO_ENV = "production" + +[context.deploy-preview] + command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL --enableGitInfo" + +[context.branch-deploy] + command = "hugo --gc --minify -b $DEPLOY_PRIME_URL" + +[context.next.environment] + HUGO_ENABLEGITINFO = "true" + +[[headers]] + for = "/*.jpg" + + [headers.values] + Cache-Control = "public, max-age=31536000" + +[[headers]] + for = "/*.png" + + [headers.values] + Cache-Control = "public, max-age=31536000" + +[[headers]] + for = "/*.css" + + [headers.values] + Cache-Control = "public, max-age=31536000" + +[[headers]] + for = "/*.js" + + [headers.values] + Cache-Control = "public, max-age=31536000" + +[[headers]] + for = "/*.ttf" + + [headers.values] + Cache-Control = "public, max-age=31536000" diff --cc docs/package.hugo.json index 000000000,000000000..24ffc7ff5 new file mode 100644 --- /dev/null +++ b/docs/package.hugo.json @@@ -1,0 -1,0 +1,25 @@@ ++{ ++ "name": "hugoDocs", ++ "version": "1.0.0", ++ "description": "", ++ "main": "index.js", ++ "scripts": { ++ "test": "echo \"Error: no test specified\" && exit 1" ++ }, ++ "author": "", ++ "license": "", ++ "devDependencies": { ++ "@awmottaz/prettier-plugin-void-html": "~1.8.0", ++ "@tailwindcss/cli": "~4.1.0", ++ "@tailwindcss/typography": "~0.5.16", ++ "prettier": "~3.5.3", ++ "prettier-plugin-go-template": "~0.0.15", ++ "tailwindcss": "~4.1.0" ++ }, ++ "dependencies": { ++ "@alpinejs/focus": "~3.14.9", ++ "@alpinejs/persist": "~3.14.9", ++ "@hotwired/turbo": "~8.0.13", ++ "alpinejs": "~3.14.9" ++ } ++}