Squashed 'docs/' changes from fcc3ed651..a49697e53

a49697e53 Add private use subtag requirements to multilingual page
a5c6bb4da Add INFINI Pizza search engine
45b732efa Fix template lookup order for AMP pages
30c672d0b netlify: Hugo 0.133.1
7c766e724 Update page resources documentation
ca802fbec Document how to enable AsciiDoc syntax highlighting
c3350f4cf Update definition of falsy to include zero time.Time values
b0e5ab051 Fir typo
60f6cb63b Update migrations.md
ec52c7ba1 Improve formatting of example code
e5681ad01 Improve formatting of example code
bdf3ffc73 Clarify the various next/prev methods
b5505d22a Clarify template lookup order for shortcodes
cf8dd7034 Improve embedded.md
e5dee2651 Update transform.ToMath
4d419a128 Update pagination configuration to use new struct
05d4fd597 Update PrevInSection.md
fd33370ed Add new-in 0.133.0
f9062042f Add the new page config section
205645e97 Remove out-dated  new-in
3ed3673f7 Fix typo
41df91659 Document the 'else with' construct introduced with Go 1.23
9c4697ab3 netlify: Hugo 0.133.0
62506b052 Merge branch 'temp133'
877e1bfcd Add config options page.nextPrevSortOrder/nextPrevInSectionSortOrder
eb159fe62 Update menu.md
efa7795a0 Update theme
dbe8911ad netlify: Hugo 0.132.2
2f793d328 Document passthrough render hooks
a7ce9a5e8 netlify: Hugo 0.132.1
2c137cb48 Update blockquotes.md
e0fa2f0d1 Add new-in badge to blockquote render hook page
bf42bbe6b Update references to render hooks
85a3d9958 Update theme
2dae72128 Document blockquote render hooks
8f5afb55d Update plainify return type
160f22d0e netlify: Hugo 0.132.0
82b5586fb Document transform.ToMath
1efcbcddb tpl/transform: Make Plainify and ToMath return template.HTML
31727be2e docs: Regen docshelper
88a421426 Merge commit 'a6e635ca7d905d9ec3ffd708db2694f680b03aae'

git-subtree-dir: docs
git-subtree-split: a49697e536ee0d477ab4e552cfa8dc74debeff27
This commit is contained in:
Bjørn Erik Pedersen 2024-09-01 14:51:15 +02:00
parent a6e635ca7d
commit dec8cd4ada
46 changed files with 1309 additions and 447 deletions

View file

@ -1,4 +1,4 @@
{{ define "main" }} {{ define "main" }}
{{ $section_to_display := (.Site.Taxonomies.categories.fundamentals).Pages | lang.Merge (.Sites.First.Taxonomies.categories.fundamentals).Pages }} {{ $section_to_display := (.Site.Taxonomies.categories.fundamentals).Pages | lang.Merge (.Sites.Default.Taxonomies.categories.fundamentals).Pages }}
{{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }} {{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }}
{{ end }} {{ end }}

View file

@ -1,5 +1,5 @@
{{ define "main" }} {{ define "main" }}
{{ $paginator := .Paginate (.Pages | lang.Merge (where .Sites.First.RegularPages "Section" .Section)) }} {{ $paginator := .Paginate (.Pages | lang.Merge (where .Sites.Default.RegularPages "Section" .Section)) }}
{{ $section_to_display := .Sections | default $paginator.Pages }} {{ $section_to_display := .Sections | default $paginator.Pages }}
{{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }} {{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }}
{{ end }} {{ end }}

View file

@ -1,5 +1,6 @@
{{ $text := ` {{ $text := `
Most of the commands for **Hugo Modules** require a newer version of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ). If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.12 in your Environment settings. Most of the commands for **Hugo Modules** require a newer version (>= 1.18) of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ).
If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.19 or newer in your Environment settings.
For more information about Go Modules, see: For more information about Go Modules, see:

View file

@ -1 +1 @@
# github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472 # github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f

View file

@ -49,7 +49,7 @@ toc: true
: Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more. : Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more.
[Markdown render hooks] [Markdown render hooks]
: Override the conversion of Markdown to HTML when rendering fenced code blocks, headings, images, and links. For example, render every standalone image as an HTML `figure` element. : Override the conversion of Markdown to HTML when rendering blockquotes, fenced code blocks, headings, images, and links. For example, render every standalone image as an HTML `figure` element.
[Diagrams] [Diagrams]
: Use fenced code blocks and Markdown render hooks to include diagrams in your content. : Use fenced code blocks and Markdown render hooks to include diagrams in your content.

View file

@ -125,7 +125,7 @@ Set any [front matter field] in the map passed to the [`AddPage`](#addpage) meth
This table describes the fields most commonly passed to the `AddPage` method. This table describes the fields most commonly passed to the `AddPage` method.
Key|Descripion|Required Key|Description|Required
:--|:--|:-: :--|:--|:-:
`content.mediaType`|The content [media type]. Default is `text/markdown`. See [content formats] for examples.|  `content.mediaType`|The content [media type]. Default is `text/markdown`. See [content formats] for examples.| 
`content.value`|The content value as a string.|  `content.value`|The content value as a string.| 
@ -148,7 +148,7 @@ When setting the `path`, Hugo transforms the given string to a logical path. For
Construct the map passed to the [`AddResource`](#addresource) method using the fields below. Construct the map passed to the [`AddResource`](#addresource) method using the fields below.
Key|Descripion|Required Key|Description|Required
:--|:--|:-: :--|:--|:-:
`content.mediaType`|The content [media type].|:heavy_check_mark: `content.mediaType`|The content [media type].|:heavy_check_mark:
`content.value`|The content value as a string or resource.|:heavy_check_mark: `content.value`|The content value as a string or resource.|:heavy_check_mark:

View file

@ -21,15 +21,22 @@ This is the default language configuration:
In the above, `en` is the language key. In the above, `en` is the language key.
{{% note %}}
Each language key must conform to the syntax described in [RFC 5646]. You must use hyphens to separate subtags. For example: Language keys must conform to the syntax described in [RFC 5646]. For example:
- `en` - `en`
- `en-GB` - `en-US`
- `pt-BR`
Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7] are also supported. Omit the `art-x-` prefix from the language key. For example:
- `hugolang`
{{% note %}}
Private use subtags must not exceed 8 alphanumeric characters.
{{% /note %}}
[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1 [RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
{{% /note %}} [RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7
This is an example of a site configuration for a multilingual project. Any key not defined in a `languages` object will fall back to the global value in the root of your site configuration. This is an example of a site configuration for a multilingual project. Any key not defined in a `languages` object will fall back to the global value in the root of your site configuration.

View file

@ -1,6 +1,6 @@
--- ---
title: Page resources title: Page resources
description: Page resources -- images, other pages, documents, etc. -- have page-relative URLs and their own metadata. description: Use page resources to logically associate assets with a page.
categories: [content management] categories: [content management]
keywords: [bundle,content,resources] keywords: [bundle,content,resources]
menu: menu:
@ -37,82 +37,83 @@ content
└── index.md (root of page bundle) └── index.md (root of page bundle)
``` ```
## Properties ## Examples
ResourceType Use any of these methods on a `Page` object to capture page resources:
: The main type of the resource's [Media Type](/templates/output-formats/#media-types). For example, a file of MIME type `image/jpeg` has the ResourceType `image`. A `Page` will have `ResourceType` with value `page`.
Name - [`Resources.ByType`]
: Default value is the file name (relative to the owning page). Can be set in front matter. - [`Resources.Get`]
- [`Resources.GetMatch`]
- [`Resources.Match`]
Title Once you have captured a resource, use any of the applicable [`Resource`] methods to return a value or perform an action.
: Default value is the same as `.Name`. Can be set in front matter.
Permalink [`Resource`]: /methods/resource
: The absolute URL to the resource. Resources of type `page` will have no value. [`Resources.ByType`]: /methods/page/resources#bytype
[`Resources.GetMatch`]: /methods/page/resources#getmatch
[`Resources.Get`]: /methods/page/resources#get
[`Resources.Match`]: /methods/page/resources#match
RelPermalink The following examples assume this content structure:
: The relative URL to the resource. Resources of type `page` will have no value.
Content ```text
: The content of the resource itself. For most resources, this returns a string content/
with the contents of the file. Use this to create inline resources. └── example/
├── data/
│ └── books.json <-- page resource
├── images/
│ ├── a.jpg <-- page resource
│ └── b.jpg <-- page resource
├── snippets/
│ └── text.md <-- page resource
└── index.md
```
Render a single image, and throw an error if the file does not exist:
```go-html-template ```go-html-template
{{ with .Resources.GetMatch "script.js" }} {{ $path := "images/a.jpg" }}
<script>{{ .Content | safeJS }}</script> {{ with .Resources.Get $path }}
{{ end }} <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ else }}
{{ with .Resources.GetMatch "style.css" }} {{ errorf "Unable to get page resource %q" $path }}
<style>{{ .Content | safeCSS }}</style>
{{ end }}
{{ with .Resources.GetMatch "img.png" }}
<img src="data:{{ .MediaType.Type }};base64,{{ .Content | base64Encode }}">
{{ end }} {{ end }}
``` ```
MediaType.Type Render all images, resized to 300 px wide:
: The media type (formerly known as a MIME type) of the resource (e.g., `image/jpeg`).
MediaType.MainType
: The main type of the resource's media type (e.g., `image`).
MediaType.SubType
: The subtype of the resource's type (e.g., `jpeg`). This may or may not correspond to the file suffix.
MediaType.Suffixes
: A slice of possible file suffixes for the resource's media type (e.g., `[jpg jpeg jpe jif jfif]`).
## Methods
ByType
: Returns the page resources of the given type.
```go-html-template ```go-html-template
{{ .Resources.ByType "image" }} {{ range .Resources.ByType "image" }}
{{ with .Resize "300x" }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
{{ end }}
{{ end }}
``` ```
Match
: Returns all the page resources (as a slice) whose `Name` matches the given Glob pattern ([examples](https://github.com/gobwas/glob/blob/master/readme.md)). The matching is case-insensitive. Render the markdown snippet:
```go-html-template ```go-html-template
{{ .Resources.Match "images/*" }} {{ with .Resources.Get "snippets/text.md" }}
{{ .Content }}
{{ end }}
``` ```
GetMatch List the titles in the data file, and throw an error if the file does not exist.
: Same as `Match` but will return the first match.
### Pattern matching ```go-html-template
{{ $path := "data/books.json" }}
```go {{ with .Resources.Get $path }}
// Using Match/GetMatch to find this images/sunset.jpg ? {{ with . | transform.Unmarshal }}
.Resources.Match "images/sun*" ✅ <p>Books:</p>
.Resources.Match "**/sunset.jpg" ✅ <ul>
.Resources.Match "images/*.jpg" ✅ {{ range . }}
.Resources.Match "**.jpg" ✅ <li>{{ .title }}</li>
.Resources.Match "*" 🚫 {{ end }}
.Resources.Match "sunset.jpg" 🚫 </ul>
.Resources.Match "*sunset.jpg" 🚫 {{ end }}
{{ else }}
{{ errorf "Unable to get page resource %q" $path }}
{{ end }}
``` ```
## Metadata ## Metadata
@ -124,21 +125,21 @@ Resources of type `page` get `Title` etc. from their own front matter.
{{% /note %}} {{% /note %}}
name name
: Sets the value returned in `Name`. : (`string`) Sets the value returned in `Name`.
{{% note %}} {{% note %}}
The methods `Match`, `Get` and `GetMatch` use `Name` to match the resources. The methods `Match`, `Get` and `GetMatch` use `Name` to match the resources.
{{% /note %}} {{% /note %}}
title title
: Sets the value returned in `Title` : (`string`) Sets the value returned in `Title`
params params
: A map of custom key-value pairs. : (`map`) A map of custom key-value pairs.
### Resources metadata example ### Resources metadata example
{{< code-toggle >}} {{< code-toggle file=content/example.md fm=true >}}
title: Application title: Application
date : 2018-01-25 date : 2018-01-25
resources : resources :
@ -173,7 +174,7 @@ From the example above:
- Every docx in the bundle will receive the `word` icon. - Every docx in the bundle will receive the `word` icon.
{{% note %}} {{% note %}}
The __order matters__ --- Only the **first set** values of the `title`, `name` and `params`-**keys** will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule. The order matters; only the first set values of the `title`, `name` and `params` keys will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule.
{{% /note %}} {{% /note %}}
### The `:counter` placeholder in `name` and `title` ### The `:counter` placeholder in `name` and `title`

View file

@ -48,7 +48,7 @@ For a complete guide to contributing to Hugo, see the [Contribution Guide].
To build the extended edition of Hugo from source you must: To build the extended edition of Hugo from source you must:
1. Install [Git] 1. Install [Git]
1. Install [Go] version 1.20 or later 1. Install [Go] version 1.23.0 or later
1. Install a C compiler, either [GCC] or [Clang] 1. Install a C compiler, either [GCC] or [Clang]
1. Update your `PATH` environment variable as described in the [Go documentation] 1. Update your `PATH` environment variable as described in the [Go documentation]

View file

@ -2,4 +2,6 @@
# Do not remove front matter. # Do not remove front matter.
--- ---
In Go templates, the falsy values are `false`, `0`, any nil pointer or interface value, and any array, slice, map, or string of length zero. Everything else is truthy. The falsy values are `false`, `0`, any `nil` pointer or interface value, any array, slice, map, or string of length zero, and zero `time.Time` values.
Everything else is truthy.

View file

@ -34,7 +34,7 @@ Use with the [`else`] statement:
{{ end }} {{ end }}
``` ```
Use `else if` to check multiple conditions. Use `else if` to check multiple conditions:
```go-html-template ```go-html-template
{{ $var := 12 }} {{ $var := 12 }}

View file

@ -36,6 +36,20 @@ Use with the [`else`] statement:
{{ end }} {{ end }}
``` ```
Use `else with` to check multiple conditions:
```go-html-template
{{ $v1 := 0 }}
{{ $v2 := 42 }}
{{ with $v1 }}
{{ . }}
{{ else with $v2 }}
{{ . }} → 42
{{ else }}
{{ print "v1 and v2 are falsy" }}
{{ end }}
```
Initialize a variable, scoped to the current block: Initialize a variable, scoped to the current block:
```go-html-template ```go-html-template

View file

@ -6,7 +6,7 @@ keywords: []
action: action:
aliases: [plainify] aliases: [plainify]
related: [] related: []
returnType: string returnType: template.HTML
signatures: [transform.Plainify INPUT] signatures: [transform.Plainify INPUT]
aliases: [/functions/plainify] aliases: [/functions/plainify]
--- ---

View file

@ -0,0 +1,112 @@
---
title: transform.ToMath
description: Renders a math expression using KaTeX.
categories: []
keywords: []
action:
aliases: []
related:
- content-management/mathematics
returnType: types.Result[template.HTML]
signatures: ['transform.ToMath EXPRESSION [OPTIONS]']
aliases: [/functions/tomath]
toc: true
---
{{< new-in "0.132.0" >}}
{{% note %}}
This feature was introduced in Hugo 0.132.0 and is marked as experimental.
This does not mean that it's going to be removed, but this is our first use of WASI/Wasm in Hugo, and we need to see how it [works in the wild](https://github.com/gohugoio/hugo/issues/12736) before we can set it in stone.
{{% /note %}}
## Arguments
EXPRESSION
: The math expression to render using KaTeX.
OPTIONS
: A map of zero or more options.
## Options
These are a subset of the [KaTeX options].
output
: (`string`). Determines the markup language of the output. One of `html`, `mathml`, or `htmlAndMathml`. Default is `mathml`.
<!-- Indent to prevent spliting the description list. -->
With `html` and `htmlAndMathml` you must include KaTeX CSS within the `head` element of your base template. For example:
```html
<head>
...
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
...
</head>
```
displayMode
: (`bool`) If `true` render in display mode, else render in inline mode. Default is `false`.
leqno
: (`bool`) If `true` render with the equation numbers on the left. Default is `false`.
fleqn
: (`bool`) If `true` render flush left with a 2em left margin. Default is `false`.
minRuleThickness
: (`float`) The minimum thickness of the fraction lines in `em`. Default is `0.04`.
macros
: (`map`) A map of macros to be used in the math expression. Default is `{}`.
throwOnError
: (`bool`) If `true` throw a `ParseError` when KaTeX encounters an unsupported command or invalid LaTex. See [error handling]. Default is `true`.
errorColor
: (`string`) The color of the error messages expressed as an RGB [hexadecimal color]. Default is `#cc0000`.
## Examples
### Basic
```go-html-template
{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }}
```
### Macros
```go-html-template
{{ $macros := dict
"\\addBar" "\\bar{#1}"
"\\bold" "\\mathbf{#1}"
}}
{{ $opts := dict "macros" $macros }}
{{ transform.ToMath "\\addBar{y} + \\bold{H}" $opts }}
```
## Error handling
There are 3 ways to handle errors from KaTeX:
1. Let KaTeX throw an error and make the build fail. This is the default behavior.
1. Handle the error in your template. See the render hook example below.
1. Set the `throwOnError` option to `false` to make KaTeX render the expression as an error instead of throwing an error. See [options].
{{< code file=layouts/_default/_markup/render-passthrough-inline.html copy=true >}}
{{ with transform.ToMath .Inner }}
{{ with .Err }}
{{ errorf "Failed to render KaTeX: %q. See %s" . $.Position }}
{{ else }}
{{ . }}
{{ end }}
{{ end }}
{{- /* chomp trailing newline */ -}}
{{< /code >}}
[error handling]: #error-handling
[KaTeX options]: https://katex.org/docs/options.html
[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color

View file

@ -238,7 +238,7 @@ This is the default configuration for the AsciiDoc renderer:
###### attributes ###### attributes
(`map`) A map of key-value pairs, each a document attributes,See Asciidoctors [attributes]. (`map`) A map of key-value pairs, each a document attributes. See Asciidoctors [attributes].
[attributes]: https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions [attributes]: https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions
@ -302,6 +302,51 @@ To mitigate security risks, entries in the extension array may not contain forwa
my-attribute-name = "my value" my-attribute-name = "my value"
{{< /code-toggle >}} {{< /code-toggle >}}
### AsciiDoc syntax highlighting
Follow the steps below to enable syntax highlighting.
Step 1
: Set the `source-highlighter` attribute in your site configuration. For example:
{{< code-toggle file=hugo >}}
[markup.asciidocExt.attributes]
source-highlighter = 'rouge'
{{< /code-toggle >}}
Step 2
: Generate the highlighter CSS. For example:
```text
rougify style monokai.sublime > assets/css/syntax.css
```
Step 3
: In your base template add a link to the CSS file:
{{< code file=layouts/_default/baseof.html >}}
<head>
...
{{ with resources.Get "css/syntax.css" }}
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
{{ end }}
...
</head>
{{< /code >}}
Then add the code to be highlighted to your markup:
```text
[#hello,ruby]
----
require 'sinatra'
get '/hi' do
"Hello World!"
end
----
```
### AsciiDoc troubleshooting ### AsciiDoc troubleshooting
Run `hugo --logLevel debug` to examine Hugo's call to the Asciidoctor executable: Run `hugo --logLevel debug` to examine Hugo's call to the Asciidoctor executable:

View file

@ -378,6 +378,10 @@ Module configuration see [module configuration](/hugo-modules/configuration/).
See [custom output formats]. See [custom output formats].
###### page
See [configure page](#configure-page).
###### pagination ###### pagination
See [configure pagination](/templates/pagination/#configuration). See [configure pagination](/templates/pagination/#configuration).
@ -496,6 +500,50 @@ enableemoji: true
``` ```
{{% /note %}} {{% /note %}}
## Configure page
{{< new-in 0.133.0 >}}
These methods on a `Page` object navigate to the next or previous page within a page collection, relative to the current page:
- [Next](/methods/page/next/)
- [NextInSection](/methods/page/nextinsection/)
- [Prev](/methods/page/prev/)
- [PrevInSection](/methods/page/previnsection/)
Hugo determines the _next_ and _previous_ page by sorting a page collection according to this sorting hierarchy:
Field|Precedence|Sort direction
:--|:--|:--
[`weight`]|1|descending
[`date`]|2|descending
[`linkTitle`]|3|descending
[`path`]|4|descending
[`date`]: /methods/page/date/
[`weight`]: /methods/page/weight/
[`linkTitle`]: /methods/page/linktitle/
[`path`]: /methods/page/path/
The sort direction in the table above corresponds to these default site configuration values:
{{< code-toggle config=page />}}
To sort all fields in ascending order:
{{< code-toggle file=hugo >}}
[page]
nextPrevInSectionSortOrder = 'asc'
nextPrevSortOrder = 'asc'
{{< /code-toggle >}}
{{% note %}}
These settings do not apply to the [`Next`] or [`Prev`] methods on a `Pages` object.
[`Next`]: /methods/pages/next
[`Prev`]: /methods/pages/next
{{% /note %}}
## Configure build ## Configure build
The `build` configuration section contains global build-related configuration options. The `build` configuration section contains global build-related configuration options.
@ -609,8 +657,6 @@ Setting `force=true` will make a redirect even if there is existing content in t
## 404 server error page {#_404-server-error-page} ## 404 server error page {#_404-server-error-page}
{{< new-in 0.103.0 >}}
Hugo will, by default, render all 404 errors when running `hugo server` with the `404.html` template. Note that if you have already added one or more redirects to your [server configuration](#configure-server), you need to add the 404 redirect explicitly, e.g: Hugo will, by default, render all 404 errors when running `hugo server` with the `404.html` template. Note that if you have already added one or more redirects to your [server configuration](#configure-server), you need to add the 404 redirect explicitly, e.g:
{{< code-toggle file=config/development/server >}} {{< code-toggle file=config/development/server >}}
@ -924,7 +970,6 @@ output
It is recommended to put coarse grained filters (e.g. for language and output format) in the excludes section, e.g.: It is recommended to put coarse grained filters (e.g. for language and output format) in the excludes section, e.g.:
{{< code-toggle file=hugo >}} {{< code-toggle file=hugo >}}
[segments.segment1] [segments.segment1]
[[segments.segment1.excludes]] [[segments.segment1.excludes]]

View file

@ -1,13 +0,0 @@
---
cascade:
_build:
list: never
publishResources: false
render: never
---
<!--
Files within this headless branch bundle are Markdown snippets. Each file must contain front matter delimiters, though front matter fields are not required.
Include the rendered content using the "include" shortcode.
-->

View file

@ -1,37 +0,0 @@
---
# Do not remove front matter.
---
The `Next` and `Prev` methods on a `Pages` object are more flexible than the `Next` and `Prev` methods on a `Page` object.
||Page collection|Custom sort order
:--|:--|:-:
[`PAGES.Next`] and [`PAGES.Prev`]|locally defined|✔️
[`PAGE.Next`] and [`PAGE.Prev`]|globally defined|❌
[`PAGES.Next`]: /methods/pages/next/
[`PAGES.Prev`]: /methods/pages/prev/
[`PAGE.Next`]: /methods/page/next/
[`PAGE.Prev`]: /methods/page/prev/
locally defined
: Build the page collection every time you call `PAGES.Next` and `PAGES.Prev`. Navigation between pages is relative to the current page's position within the local collection, independent of the global collection.
With a local collection, the navigation sort order is the same as the collection sort order.
globally defined
: Build the page collection once, on a list page. Navigation between pages is relative to the current page's position within the global collection.
With a global collection, the navigation sort order is fixed, using Hugo's default sort order. In order of precedence:
1. Page [weight]
2. Page [date] (descending)
3. Page [linkTitle], falling back to page [title]
4. Page file path if the page is backed by a file
For example, with a global collection sorted by title, the navigation sort order will use Hugo's default sort order. This is probably not what you want or expect. For this reason, the `Next` and `Prev` methods on a `Pages` object are generally a better choice.
[date]: /methods/page/date/
[weight]: /methods/page/weight/
[linkTitle]: /methods/page/linktitle/
[title]: /methods/page/title/

View file

@ -1,6 +1,6 @@
--- ---
title: Next title: Next
description: Returns the next page in a global page collection, relative to the given page. description: Returns the next page in a site's collection of regular pages, relative to the current page.
categories: [] categories: []
keywords: [] keywords: []
action: action:
@ -12,42 +12,6 @@ action:
- methods/pages/Prev - methods/pages/Prev
returnType: page.Page returnType: page.Page
signatures: [PAGE.Next] signatures: [PAGE.Next]
toc: true
--- ---
The behavior of the `Prev` and `Next` methods on a `Page` object is probably the reverse of what you expect. {{% include "methods/page/_common/next-and-prev.md" %}}
With this content structure:
```text
content/
├── pages/
│ ├── _index.md
│ ├── page-1.md <-- front matter: weight = 10
│ ├── page-2.md <-- front matter: weight = 20
│ └── page-3.md <-- front matter: weight = 30
└── _index.md
```
When you visit page-2:
- The `Prev` method points to page-3
- The `Next` method points to page-1
{{% note %}}
Use the opposite label in your navigation links as shown in the example below.
{{% /note %}}
```go-html-template
{{ with .Next }}
<a href="{{ .RelPermalink }}">Prev</a>
{{ end }}
{{ with .Prev }}
<a href="{{ .RelPermalink }}">Next</a>
{{ end }}
```
## Compare to Pages methods
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}

View file

@ -1,71 +1,15 @@
--- ---
title: NextInSection title: NextInSection
description: Returns the next page within a section, relative to the given page. description: Returns the next regular page in a section, relative to the given page.
categories: [] categories: []
keywords: [] keywords: []
action: action:
related: related:
- methods/page/PrevInSection - methods/page/PrevInSection
- methods/page/Next
- methods/page/Prev
- methods/pages/Next - methods/pages/Next
- methods/pages/Prev - methods/pages/Prev
returnType: page.Page returnType: page.Page
signatures: [PAGE.NextInSection] signatures: [PAGE.NextInSection]
--- ---
The behavior of the `PrevInSection` and `NextInSection` methods on a `Page` object is probably the reverse of what you expect. {{% include "methods/page/_common/nextinsection-and-previnsection.md" %}}
With this content structure:
```text
content/
├── books/
│ ├── _index.md
│ ├── book-1.md
│ ├── book-2.md
│ └── book-3.md
├── films/
│ ├── _index.md
│ ├── film-1.md
│ ├── film-2.md
│ └── film-3.md
└── _index.md
```
When you visit book-2:
- The `PrevInSection` method points to book-3
- The `NextInSection` method points to book-1
{{% note %}}
Use the opposite label in your navigation links as shown in the example below.
{{% /note %}}
```go-html-template
{{ with .NextInSection }}
<a href="{{ .RelPermalink }}">Previous in section</a>
{{ end }}
{{ with .PrevInSection }}
<a href="{{ .RelPermalink }}">Next in section</a>
{{ end }}
```
{{% note %}}
The navigation sort order may be different than the page collection sort order.
{{% /note %}}
With the `PrevInSection` and `NextInSection` methods, the navigation sort order is fixed, using Hugos default sort order. In order of precedence:
1. Page [weight]
2. Page [date] (descending)
3. Page [linkTitle], falling back to page [title]
4. Page file path if the page is backed by a file
For example, with a page collection sorted by title, the navigation sort order will use Hugos default sort order. This is probably not what you want or expect. For this reason, the Next and Prev methods on a Pages object are generally a better choice.
[date]: /methods/page/date/
[weight]: /methods/page/weight/
[linkTitle]: /methods/page/linktitle/
[title]: /methods/page/title/

View file

@ -1,53 +1,17 @@
--- ---
title: Prev title: Prev
description: Returns the previous page in a global page collection, relative to the given page. description: Returns the previous page in a site's collection of regular pages, relative to the current page.
categories: [] categories: []
keywords: [] keywords: []
action: action:
related: related:
- methods/page/Next - methods/page/Next
- methods/page/PrevInSection
- methods/page/NextInSection - methods/page/NextInSection
- methods/pages/Prev - methods/page/PrevInSection
- methods/pages/Next - methods/pages/Next
- methods/pages/Prev
returnType: page.Page returnType: page.Page
signatures: [PAGE.Prev] signatures: [PAGE.Prev]
toc: true
--- ---
The behavior of the `Prev` and `Next` methods on a `Page` object is probably the reverse of what you expect. {{% include "methods/page/_common/next-and-prev.md" %}}
With this content structure:
```text
content/
├── pages/
│ ├── _index.md
│ ├── page-1.md <-- front matter: weight = 10
│ ├── page-2.md <-- front matter: weight = 20
│ └── page-3.md <-- front matter: weight = 30
└── _index.md
```
When you visit page-2:
- The `Prev` method points to page-3
- The `Next` method points to page-1
{{% note %}}
Use the opposite label in your navigation links as shown in the example below.
{{% /note %}}
```go-html-template
{{ with .Next }}
<a href="{{ .RelPermalink }}">Prev</a>
{{ end }}
{{ with .Prev }}
<a href="{{ .RelPermalink }}">Next</a>
{{ end }}
```
## Compare to Pages methods
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}

View file

@ -1,72 +1,15 @@
--- ---
title: PrevInSection title: PrevInSection
description: Returns the previous page within a section, relative to the given page. description: Returns the previous regular page in a section, relative to the given page.
categories: [] categories: []
keywords: [] keywords: []
action: action:
related: related:
- methods/page/NextInSection - methods/page/NextInSection
- methods/page/Next
- methods/pages/Next - methods/pages/Next
- methods/page/Prev
- methods/pages/Prev - methods/pages/Prev
returnType: page.Page returnType: page.Page
signatures: [PAGE.PrevInSection] signatures: [PAGE.PrevInSection]
--- ---
{{% include "methods/page/_common/nextinsection-and-previnsection.md" %}}
The behavior of the `PrevInSection` and `NextInSection` methods on a `Page` object is probably the reverse of what you expect.
With this content structure:
```text
content/
├── books/
│ ├── _index.md
│ ├── book-1.md
│ ├── book-2.md
│ └── book-3.md
├── films/
│ ├── _index.md
│ ├── film-1.md
│ ├── film-2.md
│ └── film-3.md
└── _index.md
```
When you visit book-2:
- The `PrevInSection` method points to book-3
- The `NextInSection` method points to book-1
{{% note %}}
Use the opposite label in your navigation links as shown in the example below.
{{% /note %}}
```go-html-template
{{ with .NextInSection }}
<a href="{{ .RelPermalink }}">Previous in section</a>
{{ end }}
{{ with .PrevInSection }}
<a href="{{ .RelPermalink }}">Next in section</a>
{{ end }}
```
{{% note %}}
The navigation sort order may be different than the page collection sort order.
{{% /note %}}
With the `PrevInSection` and `NextInSection` methods, the navigation sort order is fixed, using Hugos default sort order. In order of precedence:
1. Page [weight]
2. Page [date] (descending)
3. Page [linkTitle], falling back to page [title]
4. Page file path if the page is backed by a file
For example, with a page collection sorted by title, the navigation sort order will use Hugos default sort order. This is probably not what you want or expect. For this reason, the Next and Prev methods on a Pages object are generally a better choice.
[date]: /methods/page/date/
[weight]: /methods/page/weight/
[linkTitle]: /methods/page/linktitle/
[title]: /methods/page/title/

View file

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

View file

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

View file

@ -1,55 +1,17 @@
--- ---
title: Next title: Next
description: Returns the next page in a local page collection, relative to the given page. description: Returns the next page in a page collection, relative to the given page.
categories: [] categories: []
keywords: [] keywords: []
action: action:
related: related:
- methods/pages/Prev - methods/pages/Prev
- methods/page/Next - methods/page/Next
- methods/page/NextInSection
- methods/page/Prev - methods/page/Prev
- methods/page/NextInSection
- methods/page/PrevInSection - methods/page/PrevInSection
returnType: page.Page returnType: page.Page
signatures: [PAGES.Next PAGE] signatures: [PAGES.Next PAGE]
toc: true
--- ---
The behavior of the `Prev` and `Next` methods on a `Pages` objects is probably the reverse of what you expect. {{% include "methods/pages/_common/next-and-prev.md" %}}
With this content structure and the page collection sorted by weight in ascending order:
```text
content/
├── pages/
│ ├── _index.md
│ ├── page-1.md <-- front matter: weight = 10
│ ├── page-2.md <-- front matter: weight = 20
│ └── page-3.md <-- front matter: weight = 30
└── _index.md
```
When you visit page-2:
- The `Prev` method points to page-3
- The `Next` method points to page-1
{{% note %}}
Use the opposite label in your navigation links as shown in the example below.
{{% /note %}}
```go-html-template
{{ $pages := where .Site.RegularPages.ByWeight "Section" "pages" }}
{{ with $pages.Next . }}
<a href="{{ .RelPermalink }}">Previous</a>
{{ end }}
{{ with $pages.Prev . }}
<a href="{{ .RelPermalink }}">Next</a>
{{ end }}
```
## Compare to Page methods
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}

View file

@ -1,55 +1,17 @@
--- ---
title: Prev title: Prev
description: Returns the previous page in a local page collection, relative to the given page. description: Returns the previous page in a page collection, relative to the given page.
categories: [] categories: []
keywords: [] keywords: []
action: action:
related: related:
- methods/pages/Next - methods/pages/Next
- methods/page/Next - methods/page/Next
- methods/page/NextInSection
- methods/page/Prev - methods/page/Prev
- methods/page/NextInSection
- methods/page/PrevInSection - methods/page/PrevInSection
returnType: page.Pages returnType: page.Pages
signatures: [PAGES.Prev PAGE] signatures: [PAGES.Prev PAGE]
toc: true
--- ---
The behavior of the `Prev` and `Next` methods on a `Pages` objects is probably the reverse of what you expect. {{% include "methods/pages/_common/next-and-prev.md" %}}
With this content structure and the page collection sorted by weight in ascending order:
```text
content/
├── pages/
│ ├── _index.md
│ ├── page-1.md <-- front matter: weight = 10
│ ├── page-2.md <-- front matter: weight = 20
│ └── page-3.md <-- front matter: weight = 30
└── _index.md
```
When you visit page-2:
- The `Prev` method points to page-3
- The `Next` method points to page-1
{{% note %}}
Use the opposite label in your navigation links as shown in the example below.
{{% /note %}}
```go-html-template
{{ $pages := where .Site.RegularPages.ByWeight "Section" "pages" }}
{{ with $pages.Next . }}
<a href="{{ .RelPermalink }}">Previous</a>
{{ end }}
{{ with $pages.Prev . }}
<a href="{{ .RelPermalink }}">Next</a>
{{ end }}
```
## Compare to Page methods
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}

View file

@ -0,0 +1,72 @@
---
# Do not remove front matter.
---
Hugo determines the _next_ and _previous_ page by sorting the page collection according to this sorting hierarchy:
Field|Precedence|Sort direction
:--|:--|:--
[`weight`]|1|descending
[`date`]|2|descending
[`linkTitle`]|3|descending
[`path`]|4|descending
[`date`]: /methods/page/date/
[`weight`]: /methods/page/weight/
[`linkTitle`]: /methods/page/linktitle/
[`path`]: /methods/page/path/
The sorted page collection used to determine the _next_ and _previous_ page is independent of other page collections, which may lead to unexpected behavior.
For example, with this content structure:
```text
content/
├── pages/
│ ├── _index.md
│ ├── page-1.md <-- front matter: weight = 10
│ ├── page-2.md <-- front matter: weight = 20
│ └── page-3.md <-- front matter: weight = 30
└── _index.md
```
And these templates:
{{< code file=layouts/_default/list.html >}}
{{ range .Pages.ByWeight}}
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}
{{< /code >}}
{{< code file=layouts/_default/single.html >}}
{{ $pages := .CurrentSection.Pages.ByWeight }}
{{ with $pages.Prev . }}
<a href="{{ .RelPermalink }}">Previous</a>
{{ end }}
{{ with $pages.Next . }}
<a href="{{ .RelPermalink }}">Next</a>
{{ end }}
{{< /code >}}
When you visit page-2:
- The `Prev` method points to page-3
- The `Next` method points to page-1
To reverse the meaning of _next_ and _previous_ you can chain the [`Reverse`] method to the page collection definition:
{{< code file=layouts/_default/single.html >}}
{{ $pages := .CurrentSection.Pages.ByWeight.Reverse }}
{{ with $pages.Prev . }}
<a href="{{ .RelPermalink }}">Previous</a>
{{ end }}
{{ with $pages.Next . }}
<a href="{{ .RelPermalink }}">Next</a>
{{ end }}
{{< /code >}}
[`Reverse`]: /methods/pages/reverse/

View file

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

View file

@ -7,8 +7,8 @@ keywords: []
menu: menu:
docs: docs:
parent: render-hooks parent: render-hooks
weight: 30 weight: 40
weight: 30 weight: 40
toc: true toc: true
--- ---

View file

@ -7,8 +7,8 @@ keywords: []
menu: menu:
docs: docs:
parent: render-hooks parent: render-hooks
weight: 40 weight: 50
weight: 40 weight: 50
toc: true toc: true
--- ---
@ -24,7 +24,9 @@ Heading render hook templates receive the following [context]:
###### Attributes ###### Attributes
(`map`) The Markdown attributes, available if you configure your site as follows: (`map`) The [Markdown attributes], available if you configure your site as follows:
[Markdown attributes]: /content-management/markdown-attributes/
{{< code-toggle file=hugo >}} {{< code-toggle file=hugo >}}
[markup.goldmark.parser.attribute] [markup.goldmark.parser.attribute]

View file

@ -7,8 +7,8 @@ keywords: []
menu: menu:
docs: docs:
parent: render-hooks parent: render-hooks
weight: 50 weight: 60
weight: 50 weight: 60
toc: true toc: true
--- ---
@ -32,7 +32,9 @@ Image render hook templates receive the following context:
###### Attributes ###### Attributes
(`map`) The Markdown attributes, available if you configure your site as follows: (`map`) The [Markdown attributes], available if you configure your site as follows:
[Markdown attributes]: /content-management/markdown-attributes/
{{< code-toggle file=hugo >}} {{< code-toggle file=hugo >}}
[markup.goldmark.parser] [markup.goldmark.parser]

View file

@ -13,10 +13,12 @@ weight: 20
When rendering Markdown to HTML, render hooks override the conversion. Each render hook is a template, with one template for each supported element type: When rendering Markdown to HTML, render hooks override the conversion. Each render hook is a template, with one template for each supported element type:
- [Blockquotes](/render-hooks/blockquotes)
- [Code blocks](/render-hooks/code-blocks) - [Code blocks](/render-hooks/code-blocks)
- [Headings](/render-hooks/headings) - [Headings](/render-hooks/headings)
- [Images](/render-hooks/images) - [Images](/render-hooks/images)
- [Links](/render-hooks/links) - [Links](/render-hooks/links)
- [Passthrough elements](/render-hooks/passthrough)
{{% note %}} {{% note %}}
Hugo supports multiple [content formats] including Markdown, HTML, AsciiDoc, Emacs Org Mode, Pandoc, and reStructuredText. Hugo supports multiple [content formats] including Markdown, HTML, AsciiDoc, Emacs Org Mode, Pandoc, and reStructuredText.
@ -54,6 +56,7 @@ Each render hook is a template, with one template for each supported element typ
layouts/ layouts/
└── _default/ └── _default/
└── _markup/ └── _markup/
├── render-blockquote.html
├── render-codeblock.html ├── render-codeblock.html
├── render-heading.html ├── render-heading.html
├── render-image.html ├── render-image.html

View file

@ -7,8 +7,8 @@ keywords: []
menu: menu:
docs: docs:
parent: render-hooks parent: render-hooks
weight: 60 weight: 70
weight: 60 weight: 70
toc: true toc: true
--- ---

View file

@ -0,0 +1,125 @@
---
title: Passthrough render hooks
linkTitle: Passthrough
description: Create a passthrough render hook to override the rendering of text snippets captured by the Goldmark passthrough extension.
categories: [render hooks]
keywords: []
menu:
docs:
parent: render-hooks
weight: 80
weight: 80
toc: true
---
{{< new-in 0.132.0 >}}
## Overview
Hugo uses [Goldmark] to render Markdown to HTML. Goldmark supports custom extensions to extend its core functionality. The Goldmark [passthrough extension] captures and preserves raw Markdown within delimited snippets of text, including the delimiters themselves. These are known as _passthrough elements_.
[Goldmark]: https://github.com/yuin/goldmark
[passthrough extension]: /getting-started/configuration-markup/#passthrough
Depending on your choice of delimiters, Hugo will classify a passthrough element as either _block_ or _inline_. Consider this contrived example:
{{< code file=content/sample.md >}}
This is a
\[block\]
passthrough element with opening and closing block delimiters.
This is an \(inline\) passthrough element with opening and closing inline delimiters.
{{< /code >}}
Update your site configuration to enable the passthrough extension and define opening and closing delimiters for each passthrough element type, either `block` or `inline`. For example:
{{< code-toggle file=hugo >}}
[markup.goldmark.extensions.passthrough]
enable = true
[markup.goldmark.extensions.passthrough.delimiters]
block = [['\[', '\]'], ['$$', '$$']]
inline = [['\(', '\)']]
{{< /code-toggle >}}
In the example above there are two sets of `block` delimiters. You may use either one in your Markdown.
The Goldmark passthrough extension is often used in conjunction with the MathJax or KaTeX display engine to render [mathematical expressions] written in [LaTeX] or [Tex].
[mathematical expressions]: /content-management/mathematics/
[LaTeX]: https://www.latex-project.org/
[Tex]: https://en.wikipedia.org/wiki/TeX
To enable custom rendering of passthrough elements, create a render hook.
## Context
Passthrough render hook templates receive the following [context]:
[context]: /getting-started/glossary/#context
###### Attributes
(`map`) The [Markdown attributes], available if you configure your site as follows:
[Markdown attributes]: /content-management/markdown-attributes/
{{< code-toggle file=hugo >}}
[markup.goldmark.parser.attribute]
block = true
{{< /code-toggle >}}
Hugo populates the `Attributes` map for _block_ passthrough elements. Markdown attributes are not applicable to _inline_ elements.
###### Inner
(`string`) The inner content of the passthrough element, excluding the delimiters.
###### Ordinal
(`int`) The zero-based ordinal of the passthrough element on the page.
###### Page
(`page`) A reference to the current page.
###### PageInner
(`page`) A reference to a page nested via the [`RenderShortcodes`] method. [See details](#pageinner-details).
[`RenderShortcodes`]: /methods/page/rendershortcodes
###### Position
(`string`) The position of the passthrough element within the page content.
###### Type
(`bool`) The passthrough element type, either `block` or `inline`.
## Example
As an alternative to rendering mathematical expressions with the MathJax or KaTeX display engine, create a passthrough render hook which calls the [`transform.ToMath`] function:
[`transform.ToMath`]: /functions/transform/tomath/
{{< code file=layouts/_default/_markup/render-passthrough.html copy=true >}}
{{ if eq .Type "block" }}
{{ $opts := dict "displayMode" true }}
{{ transform.ToMath .Inner $opts }}
{{ else }}
{{ transform.ToMath .Inner }}
{{ end }}
{{< /code >}}
Although you can use one template with conditional logic as shown above, you can also create separate templates for each [`Type`](#type) of passthrough element:
```text
layouts/
└── _default/
└── _markup/
├── render-passthrough-block.html
└── render-passthrough-inline.html
```
{{% include "/render-hooks/_common/pageinner.md" %}}

View file

@ -135,7 +135,7 @@ tags = []
Hugo uses the page title and description for the title and description metadata. 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. The first 6 URLs from the `images` array are used for image metadata.
If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*` or `*cover*,*thumbnail*` are used for image metadata. If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata.
Various optional metadata can also be set: Various optional metadata can also be set:
@ -203,7 +203,7 @@ description = "Text about this post"
images = ["post-cover.png"] images = ["post-cover.png"]
{{</ code-toggle >}} {{</ code-toggle >}}
If `images` aren't specified in the page front-matter, then hugo searches for [image page resources](/content-management/image-processing/) with `feature`, `cover`, or `thumbnail` in their name. If [page bundles](/content-management/page-bundles/) are used and the `images` array is empty or undefined, images with file names matching `*feature*`, `*cover*`, or `*thumbnail*` are used for image metadata.
If no image resources with those names are found, the images defined in the [site config](/getting-started/configuration/) are used instead. If no image resources with those names are found, the images defined in the [site config](/getting-started/configuration/) are used instead.
If no images are found at all, then an image-less Twitter `summary` card is used instead of `summary_large_image`. If no images are found at all, then an image-less Twitter `summary` card is used instead of `summary_large_image`.

View file

@ -509,6 +509,20 @@ See documentation for [`with`], [`else`], and [`end`].
{{ end }} {{ end }}
``` ```
To test multiple conditions:
```go-html-template
{{ $v1 := 0 }}
{{ $v2 := 42 }}
{{ with $v1 }}
{{ . }}
{{ else with $v2 }}
{{ . }} → 42
{{ else }}
{{ print "v1 and v2 are falsy" }}
{{ end }}
```
### Access site parameters ### Access site parameters
See documentation for the [`Params`](/methods/site/params/) method on a `Site` object. See documentation for the [`Params`](/methods/site/params/) method on a `Site` object.

View file

@ -129,5 +129,5 @@ Hugo provides two methods to localize your menu entries. See [multilingual].
[localize the menu entries]: /content-management/multilingual/#menus [localize the menu entries]: /content-management/multilingual/#menus
[menu entry defined in front matter]: /content-management/menus/#example-front-matter [menu entry defined in front matter]: /content-management/menus/#example-front-matter
[menu entry defined in site configuration]: /content-management/menus/#example-site-configuration [menu entry defined in site configuration]: /content-management/menus/#example-site-configuration
[menu and methods]: /methods/menu/ [menu methods]: /methods/menu/
[multilingual]: /content-management/multilingual/#menus [multilingual]: /content-management/multilingual/#menus

View file

@ -37,12 +37,29 @@ You can organize your shortcodes in subdirectories, e.g. in `layouts/shortcodes/
Note the forward slash. Note the forward slash.
### Shortcode template lookup order ### Template lookup order
Shortcode templates have a simple [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.
1. `/layouts/shortcodes/<SHORTCODE>.html` Shortcode name|Output format|Language|Template path
2. `/themes/<THEME>/layouts/shortcodes/<SHORTCODE>.html` :--|:--|:--|:--
foo|html|en|layouts/shortcodes/foo.en.html
foo|html|en|layouts/shortcodes/foo.html.html
foo|html|en|layouts/shortcodes/foo.html
foo|html|en|layouts/shortcodes/foo.html.en.html
Shortcode name|Output format|Language|Template path
:--|:--|:--|:--
foo|rss|en|layouts/shortcodes/foo.en.xml
foo|rss|en|layouts/shortcodes/foo.rss.xml
foo|rss|en|layouts/shortcodes/foo.en.html
foo|rss|en|layouts/shortcodes/foo.rss.en.xml
foo|rss|en|layouts/shortcodes/foo.xml
foo|rss|en|layouts/shortcodes/foo.html.en.html
foo|rss|en|layouts/shortcodes/foo.html.html
foo|rss|en|layouts/shortcodes/foo.html
Note that templates provided by a theme or module always take precedence.
### Positional vs. named arguments ### Positional vs. named arguments

View file

@ -13,9 +13,9 @@ toc: true
aliases: [/developer-tools/migrations/, /developer-tools/migrated/] aliases: [/developer-tools/migrations/, /developer-tools/migrated/]
--- ---
This section highlights some projects around Hugo that are independently developed. These tools try to extend the functionality of our static site generator or help you to get started. This section highlights some independently developed projects related to Hugo. These tools extend functionality or help you to get started.
Take a look at this list of migration tools if you currently use other blogging tools like Jekyll or WordPress but intend to switch to Hugo instead. They'll take care to export your content into Hugo-friendly formats. Take a look at this list of migration tools if you currently use other blogging tools like Jekyll or WordPress but intend to switch to Hugo instead. They'll help you export your content into Hugo-friendly formats.
## Jekyll ## Jekyll
@ -35,18 +35,18 @@ Alternatively, you can use the [Jekyll import command](/commands/hugo_import_jek
## DokuWiki ## DokuWiki
[dokuwiki-to-hugo](https://github.com/wgroeneveld/dokuwiki-to-hugo) [dokuwiki-to-hugo](https://github.com/wgroeneveld/dokuwiki-to-hugo)
: Migrates your DokuWiki source pages from [DokuWiki syntax](https://www.dokuwiki.org/wiki:syntax) to Hugo Markdown syntax. Includes extra's like the TODO plugin. Written with extensibility in mind using python 3. Also generates a TOML header for each page. Designed to copypaste the wiki directory into your /content directory. : Migrates your DokuWiki source pages from [DokuWiki syntax](https://www.dokuwiki.org/wiki:syntax) to Hugo Markdown syntax. Includes extras like the TODO plugin. Written with extensibility in mind using Python 3. Also generates a TOML header for each page. Designed to copy-paste the wiki directory into your /content directory.
## WordPress ## WordPress
[wordpress-to-hugo-exporter](https://github.com/SchumacherFM/wordpress-to-hugo-exporter) [wordpress-to-hugo-exporter](https://github.com/SchumacherFM/wordpress-to-hugo-exporter)
: A one-click WordPress plugin that converts all posts, pages, taxonomies, metadata, and settings to Markdown and YAML which can be dropped into Hugo. (Note: If you have trouble using this plugin, you can [export your site for Jekyll](https://wordpress.org/plugins/jekyll-exporter/) and use Hugo's built in Jekyll converter listed above.) : A one-click WordPress plugin that converts all posts, pages, taxonomies, metadata, and settings to Markdown and YAML which can be dropped into Hugo. (Note: If you have trouble using this plugin, you can [export your site for Jekyll](https://wordpress.org/plugins/jekyll-exporter/) and use Hugo's built-in Jekyll converter listed above.)
[blog2md](https://github.com/palaniraja/blog2md) [blog2md](https://github.com/palaniraja/blog2md)
: Works with [exported xml](https://en.support.wordpress.com/export/) file of your free YOUR-TLD.wordpress.com website. It also saves approved comments to `YOUR-POST-NAME-comments.md` file along with posts. : Works with [exported xml](https://en.support.wordpress.com/export/) file of your free YOUR-TLD.wordpress.com website. It also saves approved comments to `YOUR-POST-NAME-comments.md` file along with posts.
[wordhugopress](https://github.com/nantipov/wordhugopress) [wordhugopress](https://github.com/nantipov/wordhugopress)
: A small utility written in Java, exports the entire WordPress site from the database and resource (e.g. images) files stored locally or remotely. Therefore, migration from the backup files is possible. Supports merging of the multiple WordPress sites into a single Hugo one. : A small utility written in Java that exports the entire WordPress site from the database and resource (e.g., images) files stored locally or remotely. Therefore, migration from the backup files is possible. Supports merging multiple WordPress sites into a single Hugo site.
[wp2hugo](https://github.com/ashishb/wp2hugo) [wp2hugo](https://github.com/ashishb/wp2hugo)
: A Go-based CLI tool to migrate WordPress website to Hugo while preserving original URLs, GUIDs (for feeds), image URLs, code highlights, table of contents, YouTube embeds, Google Maps embeds, and original WordPress navigation categories. : A Go-based CLI tool to migrate WordPress website to Hugo while preserving original URLs, GUIDs (for feeds), image URLs, code highlights, table of contents, YouTube embeds, Google Maps embeds, and original WordPress navigation categories.
@ -57,7 +57,7 @@ Alternatively, you can use the [Jekyll import command](/commands/hugo_import_jek
: A simple Medium to Hugo exporter able to import stories in one command, including front matter. : A simple Medium to Hugo exporter able to import stories in one command, including front matter.
[medium-to-hugo](https://github.com/bgadrian/medium-to-hugo) [medium-to-hugo](https://github.com/bgadrian/medium-to-hugo)
: CLI tool written in Go to export medium posts into a Hugo compatible Markdown format. Tags and images are included. All images will be downloaded locally and linked appropriately. : A CLI tool written in Go to export medium posts into a Hugo-compatible Markdown format. Tags and images are included. All images will be downloaded locally and linked appropriately.
## Tumblr ## Tumblr
@ -68,7 +68,7 @@ Alternatively, you can use the [Jekyll import command](/commands/hugo_import_jek
: Export all your Tumblr content to Hugo Markdown files with preserved original formatting. : Export all your Tumblr content to Hugo Markdown files with preserved original formatting.
[Tumblr to Hugo](https://github.com/jipiboily/tumblr-to-hugo) [Tumblr to Hugo](https://github.com/jipiboily/tumblr-to-hugo)
: A migration tool that converts each of your Tumblr posts to a content file with a proper title and path. Furthermore, "Tumblr to Hugo" creates a CSV file with the original URL and the new path on Hugo, to help you setup the redirections. : A migration tool that converts each of your Tumblr posts to a content file with a proper title and path. It also generates a CSV file to help you set up URL redirects.
## Drupal ## Drupal

View file

@ -43,6 +43,10 @@ A static website with a dynamic search function? Yes, Hugo provides an alternati
[Hugo Lyra](https://github.com/paolomainardi/hugo-lyra) [Hugo Lyra](https://github.com/paolomainardi/hugo-lyra)
: Hugo-Lyra is a JavaScript module to integrate [Lyra](https://github.com/LyraSearch/lyra) into a Hugo website. It contains the server-side part to generate the index and the client-side library (optional) to bootstrap the search engine easily. : Hugo-Lyra is a JavaScript module to integrate [Lyra](https://github.com/LyraSearch/lyra) into a Hugo website. It contains the server-side part to generate the index and the client-side library (optional) to bootstrap the search engine easily.
[INFINI Pizza for WebAssembly](https://github.com/infinilabs/pizza-docsearch)
: Pizza is a super-lightweight yet fully featured search engine written in Rust. You can quickly add offline search functionality to your Hugo website in just five minutes with only three lines of code. For a step-by-step guide on integrating it with Hugo, check out [this blog tutorial](https://dev.to/medcl/adding-search-functionality-to-a-hugo-static-site-based-on-infini-pizza-for-webassembly-4h5e).
## Commercial ## Commercial
[Algolia](https://www.algolia.com/) [Algolia](https://www.algolia.com/)

View file

@ -978,6 +978,9 @@ config:
images: images:
dir: :resourceDir/_gen dir: :resourceDir/_gen
maxAge: -1 maxAge: -1
misc:
dir: :cacheDir/:project
maxAge: -1
modules: modules:
dir: :cacheDir/modules dir: :cacheDir/modules
maxAge: -1 maxAge: -1
@ -1597,6 +1600,9 @@ config:
term: term:
- html - html
- rss - rss
page:
nextPrevInSectionSortOrder: desc
nextPrevSortOrder: desc
paginate: 0 paginate: 0
paginatePath: "" paginatePath: ""
pagination: pagination:
@ -1781,6 +1787,8 @@ config_helpers:
_merge: shallow _merge: shallow
outputs: outputs:
_merge: none _merge: none
page:
_merge: none
pagination: pagination:
_merge: none _merge: none
params: params:
@ -1857,7 +1865,7 @@ output:
- layouts/_default/demolayout-baseof.html - layouts/_default/demolayout-baseof.html
- layouts/_default/single-baseof.html - layouts/_default/single-baseof.html
- layouts/_default/baseof.html - layouts/_default/baseof.html
- Example: AMP single page - Example: AMP single page in "posts" section
Kind: page Kind: page
OutputFormat: amp OutputFormat: amp
Suffix: html Suffix: html
@ -1866,17 +1874,17 @@ output:
- layouts/posts/single.html - layouts/posts/single.html
- layouts/_default/single.amp.html - layouts/_default/single.amp.html
- layouts/_default/single.html - layouts/_default/single.html
- Example: AMP single page, French language - Example: AMP single page in "posts" section, French language
Kind: page Kind: page
OutputFormat: html OutputFormat: amp
Suffix: html Suffix: html
Template Lookup Order: Template Lookup Order:
- layouts/posts/single.fr.html.html - layouts/posts/single.fr.amp.html
- layouts/posts/single.html.html - layouts/posts/single.amp.html
- layouts/posts/single.fr.html - layouts/posts/single.fr.html
- layouts/posts/single.html - layouts/posts/single.html
- layouts/_default/single.fr.html.html - layouts/_default/single.fr.amp.html
- layouts/_default/single.html.html - layouts/_default/single.amp.html
- layouts/_default/single.fr.html - layouts/_default/single.fr.html
- layouts/_default/single.html - layouts/_default/single.html
- Example: Home page - Example: Home page
@ -2442,9 +2450,7 @@ tpl:
EchoParam returns the value in the collection c with key k if is set; otherwise, it returns an EchoParam returns the value in the collection c with key k if is set; otherwise, it returns an
empty string. empty string.
Deprecated: Use the index function instead. Deprecated: Use the index function instead.
Examples: Examples: []
- - '{{ echoParam .Params "langCode" }}'
- en
First: First:
Aliases: Aliases:
- first - first
@ -4673,6 +4679,11 @@ tpl:
{ {
"title": "Hello World" "title": "Hello World"
} }
ToMath:
Aliases: null
Args: null
Description: ""
Examples: null
Unmarshal: Unmarshal:
Aliases: Aliases:
- unmarshal - unmarshal

2
go.mod
View file

@ -2,4 +2,4 @@ module github.com/gohugoio/hugoDocs
go 1.16 go 1.16
require github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472 // indirect require github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f // indirect

4
go.sum
View file

@ -10,3 +10,7 @@ github.com/gohugoio/gohugoioTheme v0.0.0-20240623150114-cc7096eab3fd h1:I8X7c0oB
github.com/gohugoio/gohugoioTheme v0.0.0-20240623150114-cc7096eab3fd/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= github.com/gohugoio/gohugoioTheme v0.0.0-20240623150114-cc7096eab3fd/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM=
github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472 h1:AYZUibKKFRBp2VCQpDHW+JmQKvCvyhX7z7/SOLUSCcw= github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472 h1:AYZUibKKFRBp2VCQpDHW+JmQKvCvyhX7z7/SOLUSCcw=
github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM= github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM=
github.com/gohugoio/gohugoioTheme v0.0.0-20240812175901-cc0ef8e4a14a h1:E3JbZo69eqFBz6B+meQlKyy/ZBZQ73ldVDw8TADiIrQ=
github.com/gohugoio/gohugoioTheme v0.0.0-20240812175901-cc0ef8e4a14a/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM=
github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f h1:Eo5z3uUYfmrtIxQvHm388dFOERZwWGTjLuUO6vobzLc=
github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f/go.mod h1:GOYeAPQJ/ok8z7oz1cjfcSlsFpXrmx6VkzQ5RpnyhZM=

View file

@ -5,7 +5,6 @@ defaultContentLanguage = "en"
enableEmoji = true enableEmoji = true
ignoreErrors = ["error-remote-getjson", "error-missing-instagram-accesstoken"] ignoreErrors = ["error-remote-getjson", "error-missing-instagram-accesstoken"]
languageCode = "en-us" languageCode = "en-us"
paginate = 100
pluralizeListTitles = false pluralizeListTitles = false
timeZone = "Europe/Oslo" timeZone = "Europe/Oslo"
title = "Hugo" title = "Hugo"
@ -13,6 +12,9 @@ title = "Hugo"
# We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below). # We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below).
disableAliases = true disableAliases = true
[pagination]
pagerSize = 100
[services.googleAnalytics] [services.googleAnalytics]
ID = 'G-MBZGKNMDWC' ID = 'G-MBZGKNMDWC'

381
layouts/shortcodes/img.html Normal file
View file

@ -0,0 +1,381 @@
{{- /*
Renders the given image using the given filter, if any.
@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.
@returns {template.HTML}
@examples
{{< img src="zion-national-park.jpg" >}}
{{< img src="zion-national-park.jpg" alt="Zion National Park" >}}
{{< img
src="zion-national-park.jpg"
alt="Zion National Park"
filter="grayscale"
>}}
{{< img
src="zion-national-park.jpg"
alt="Zion National Park"
filter="process"
filterArgs="resize 400x webp"
>}}
{{< img
src="zion-national-park.jpg"
alt="Zion National Park"
filter="colorize"
filterArgs="180,50,20"
>}}
{{< img
src="zion-national-park.jpg"
alt="Zion National Park"
filter="grayscale"
example=true
>}}
{{< img
src="zion-national-park.jpg"
alt="Zion National Park"
filter="grayscale"
example=true
exampleWidth=400
>}}
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)
{{< img
src="images/examples/zion-national-park.jpg"
alt="Zion National Park"
filter="Text"
filterArgs="Zion National Park,25,250,56"
example=true
>}}
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
{{< img
src="images/examples/zion-national-park.jpg"
alt="Zion National Park"
filter="Padding"
filterArgs="20,50,20,50,#0705"
example=true
>}}
*/}}
{{- /* 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/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" "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 "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. */}}
{{- if $example }}
<p>Original</p>
<img class='di ba b--black-20' style="width: initial;" src="{{ $i.RelPermalink }}" alt="{{ $alt }}">
<p>Processed</p>
<img class='di ba b--black-20' style="width: initial;" src="{{ $fi.RelPermalink }}" alt="{{ $alt }}">
{{- else -}}
<img class='di' style="width: initial;" src="{{ $fi.RelPermalink }}" alt="{{ $alt }}">
{{- end }}
{{- define "validate-arg-count" }}
{{- $msg := "When using the %q filter, the %q shortcode requires an args parameter with %d %s. See %s" }}
{{- if lt (len .args) .argsRequired }}
{{- $text := "values" }}
{{- if eq 1 .argsRequired }}
{{- $text = "value" }}
{{- end }}
{{- errorf $msg .filter .name .argsRequired $text .position }}
{{- end }}
{{- end }}
{{- define "validate-arg-value" }}
{{- $msg := "The %q argument passed to the %q shortcode is invalid. Expected a value in the range [%v,%v], but received %v. See %s" }}
{{- if or (lt .argValue .min) (gt .argValue .max) }}
{{- errorf $msg .argName .name .min .max .argValue .position }}
{{- end }}
{{- end }}
{{- define "partials/inline/get-resource.html" }}
{{- $r := "" }}
{{- $u := urls.Parse .src }}
{{- $msg := "The %q shortcode was unable to resolve %s. See %s" }}
{{- if $u.IsAbs }}
{{- with resources.GetRemote $u.String }}
{{- with .Err }}
{{- errorf "%s" }}
{{- else }}
{{- /* This is a remote resource. */}}
{{- $r = . }}
{{- end }}
{{- else }}
{{- errorf $msg $.name $u.String $.position }}
{{- 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 -}}

View file

@ -3,7 +3,7 @@
command = "hugo --gc --minify" command = "hugo --gc --minify"
[build.environment] [build.environment]
HUGO_VERSION = "0.131.0" HUGO_VERSION = "0.133.1"
[context.production.environment] [context.production.environment]
HUGO_ENV = "production" HUGO_ENV = "production"