diff options
Diffstat (limited to 'docs/content/en/functions')
132 files changed, 5558 insertions, 0 deletions
diff --git a/docs/content/en/functions/GetPage.md b/docs/content/en/functions/GetPage.md new file mode 100644 index 000000000..aa5e9323f --- /dev/null +++ b/docs/content/en/functions/GetPage.md @@ -0,0 +1,88 @@ +--- +title: .GetPage +description: "Gets a `Page` of a given `path`." +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [sections,lists,indexes] +signature: [".GetPage PATH"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +`.GetPage` returns a page of a given `path`. Both `Site` and `Page` implements this method. The `Page` variant will, if given a relative path -- i.e. a path without a leading `/` -- try look for the page relative to the current page. + +{{% note %}} +**Note:** We overhauled and simplified the `.GetPage` API in Hugo 0.45. Before that you needed to provide a `Kind` attribute in addition to the path, e.g. `{{ .Site.GetPage "section" "blog" }}`. This will still work, but is now superfluous. +{{% /note %}} + + +```go-html-template +{{ with .Site.GetPage "/blog" }}{{ .Title }}{{ end }} +``` + +This method will return `nil` when no page could be found, so the above will not print anything if the blog section is not found. + +To find a regular page in the blog section:: + +```go-html-template +{{ with .Site.GetPage "/blog/my-post.md" }}{{ .Title }}{{ end }} +``` + +And since `Page` also provides a `.GetPage` method, the above is the same as: + +```go-html-template +{{ with .Site.GetPage "/blog" }} +{{ with .GetPage "my-post.md" }}{{ .Title }}{{ end }} +{{ end }} +``` + +## .GetPage and Multilingual Sites + +The previous examples have used the full content filename to lookup the post. Depending on how you have organized your content (whether you have the language code in the file name or not, e.g. `my-post.en.md`), you may want to do the lookup without extension. This will get you the current language's version of the page: + +```go-html-template +{{ with .Site.GetPage "/blog/my-post" }}{{ .Title }}{{ end }} +``` + +## .GetPage Example + +This code snippet---in the form of a [partial template][partials]---allows you to do the following: + +1. Grab the index object of your `tags` [taxonomy][]. +2. Assign this object to a variable, `$t` +3. Sort the terms associated with the taxonomy by popularity. +4. Grab the top two most popular terms in the taxonomy (i.e., the two most popular tags assigned to content. + +{{< code file="grab-top-two-tags.html" >}} +<ul class="most-popular-tags"> +{{ $t := .Site.GetPage "/tags" }} +{{ range first 2 $t.Data.Terms.ByCount }} + <li>{{ . }}</li> +{{ end }} +</ul> +{{< /code >}} + +## `.GetPage` on Page Bundles + +If the page retrieved by `.GetPage` is a [Leaf Bundle][leaf_bundle], and you +need to get the nested _**page** resources_ in that, you will need to use the +methods in `.Resources` as explained in the [Page Resources][page_resources] +section. + +See the [Headless Bundle][headless_bundle] documentation for an example. + + +[partials]: /templates/partials/ +[taxonomy]: /content-management/taxonomies/ +[page_kinds]: /templates/section-templates/#page-kinds +[leaf_bundle]: /content-management/page-bundles/#leaf-bundles +[headless_bundle]: /content-management/page-bundles/#headless-bundle +[page_resources]: /content-management/page-resources/ diff --git a/docs/content/en/functions/RenderString.md b/docs/content/en/functions/RenderString.md new file mode 100644 index 000000000..1b77f6a38 --- /dev/null +++ b/docs/content/en/functions/RenderString.md @@ -0,0 +1,38 @@ +--- +title: .RenderString +description: "Renders markup to HTML." +date: 2019-12-18 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [markdown,goldmark,render] +signature: [".RenderString MARKUP"] +--- + +{{< new-in "0.62.0" >}} + +`.RenderString` is a method on `Page` that renders some markup to HTML using the content renderer defined for that page (if not set in the options). + +*Note* that this method does not parse and render shortcodes. + +The method takes an optional map argument with these options: + +display ("inline") +: `inline` or `block`. If `inline` (default), surrounding `<p></p>` on short snippets will be trimmed. + +markup (defaults to the Page's markup) +: See identifiers in [List of content formats](/content-management/formats/#list-of-content-formats). + +Some examples: + +```go-html-template +{{ $optBlock := dict "display" "block" }} +{{ $optOrg := dict "markup" "org" }} +{{ "**Bold Markdown**" | $p.RenderString }} +{{ "**Bold Block Markdown**" | $p.RenderString $optBlock }} +{{ "/italic org mode/" | $p.RenderString $optOrg }} +``` + + +**Note** that this method is more powerful than the similar [markdownify](/functions/markdownify/) function as it also supports [Render Hooks](/getting-started/configuration-markup/#markdown-render-hooks) and it has options to render other markup formats. diff --git a/docs/content/en/functions/_index.md b/docs/content/en/functions/_index.md new file mode 100644 index 000000000..fa7974685 --- /dev/null +++ b/docs/content/en/functions/_index.md @@ -0,0 +1,19 @@ +--- +title: Functions Quick Reference +linktitle: Functions Quick Reference +description: Comprehensive list of Hugo templating functions, including basic and advanced usage examples. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [] +menu: + docs: + parent: "functions" +weight: 01 #rem +draft: false +aliases: [/layout/functions/,/templates/functions] +--- + +Go templates are lightweight but extensible. Go itself supplies built-in functions, including comparison operators and other basic tools. These are listed in the [Go template documentation][gofuncs]. Hugo has added additional functions to the basic template logic. + +[gofuncs]: https://golang.org/pkg/text/template/#hdr-Functions diff --git a/docs/content/en/functions/abslangurl.md b/docs/content/en/functions/abslangurl.md new file mode 100644 index 000000000..d9818fcaf --- /dev/null +++ b/docs/content/en/functions/abslangurl.md @@ -0,0 +1,27 @@ +--- +title: absLangURL +description: Adds the absolute URL with correct language prefix according to site configuration for multilingual. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [multilingual,i18n,urls] +signature: ["absLangURL INPUT"] +workson: [] +hugoversion: +relatedfuncs: [relLangURL] +deprecated: false +aliases: [] +--- + +Both `absLangURL` and [`relLangURL`](/functions/rellangurl/) are similar to their [`absURL`](/functions/absurl/) and [`relURL`](/functions/relurl) relatives but will add the correct language prefix when the site is configured with more than one language. + +So for a site `baseURL` set to `https://example.com/hugo/` and the current language is `en`: + +``` +{{ "blog/" | absLangURL }} → "https://example.com/hugo/en/blog/" +{{ "blog/" | relLangURL }} → "/hugo/en/blog/" +``` diff --git a/docs/content/en/functions/absurl.md b/docs/content/en/functions/absurl.md new file mode 100644 index 000000000..13524d2d6 --- /dev/null +++ b/docs/content/en/functions/absurl.md @@ -0,0 +1,50 @@ +--- +title: absURL +description: Creates an absolute URL based on the configured baseURL. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [urls] +signature: ["absURL INPUT"] +workson: [] +hugoversion: +relatedfuncs: [relURL] +deprecated: false +aliases: [] +--- + +Both `absURL` and `relURL` consider the configured value of `baseURL` in your site's [`config` file][configuration]. Given a `baseURL` set to `https://example.com/hugo/`: + +``` +{{ "mystyle.css" | absURL }} → "https://example.com/hugo/mystyle.css" +{{ "mystyle.css" | relURL }} → "/hugo/mystyle.css" +{{ "http://gohugo.io/" | relURL }} → "http://gohugo.io/" +{{ "http://gohugo.io/" | absURL }} → "http://gohugo.io/" +``` + +The last two examples may look strange but can be very useful. For example, the following shows how to use `absURL` in [JSON-LD structured data (SEO)][jsonld], where some of your images for a piece of content may or may not be hosted locally: + +{{< code file="layouts/partials/schemaorg-metadata.html" download="schemaorg-metadata.html" >}} +<script type="application/ld+json"> +{ + "@context" : "http://schema.org", + "@type" : "BlogPosting", + "image" : {{ apply .Params.images "absURL" "." }} +} +</script> +{{< /code >}} + +The above uses the [apply function][] and also exposes how the Go template parser JSON-encodes objects inside `<script>` tags. See [the safeJS template function][safejs] for examples of how to tell Hugo not to escape strings inside of such tags. + +{{% note "Ending Slash" %}} +`absURL` and `relURL` are smart about missing slashes, but they will *not* add a closing slash to a URL if it is not present. +{{% /note %}} + +[apply function]: /functions/apply/ +[configuration]: /getting-started/configuration/ +[jsonld]: https://developers.google.com/search/docs/guides/intro-structured-data +[safejs]: /functions/safejs diff --git a/docs/content/en/functions/adddate.md b/docs/content/en/functions/adddate.md new file mode 100644 index 000000000..56008c956 --- /dev/null +++ b/docs/content/en/functions/adddate.md @@ -0,0 +1,51 @@ +--- +title: .AddDate +description: Returns the time corresponding to adding the given number of years, months, and days passed to the function. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [dates,time] +signature: [".AddDate YEARS MONTHS DAYS"] +workson: [times] +hugoversion: +relatedfuncs: [now] +deprecated: false +aliases: [] +--- + + +The `AddDate` function takes three arguments in logical order of `years`, `months`, and `days`. + +## Example: Randomized Tweets from the Last 2 Years + +Let's assume you have a file at `data/tweets.toml` that contains a list of Tweets to display on your site's homepage. The file is filled with `[[tweet]]` blocks; e.g.--- + +{{< code-toggle file="data/tweets" >}} +[[tweet]] +name = "Steve Francia" +twitter_handle = "@spf13" +quote = "I'm creator of Hugo. #metadocreference" +link = "https://twitter.com/spf13" +date = "2017-01-07T00:00:00Z" +{{< /code-toggle >}} + +Let's assume you want to grab Tweets from the last two years and present them in a random order. In conjunction with the [`where`](/functions/where/) and [`now`](/functions/now/) functions, you can limit our range to the last two years via `now.AddDate -2 0 0`, which represents a point in time 2 years, 0 months, and 0 days before the time of your last site build. + +{{< code file="partials/templates/random-tweets.html" download="tweets.html" >}} +{{ range where $.Site.Data.tweets.tweet "date" "ge" (now.AddDate -2 0 0) | shuffle }} + <div class="item"> + <blockquote> + <p> + {{ .quote | safeHTML }} + </p> + — {{ .name }} ({{ .twitter_handle }}) <a href="{{ .link }}"> + {{ dateFormat "January 2, 2006" .date }} + </a> + </blockquote> + </div> +{{ end }} +{{< /code >}} diff --git a/docs/content/en/functions/after.md b/docs/content/en/functions/after.md new file mode 100644 index 000000000..da93b3e44 --- /dev/null +++ b/docs/content/en/functions/after.md @@ -0,0 +1,65 @@ +--- +title: after +description: "`after` slices an array to only the items after the <em>N</em>th item." +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [iteration] +signature: ["after INDEX COLLECTION"] +workson: [] +hugoversion: +relatedfuncs: [last,first,seq] +deprecated: false +aliases: [] +--- + +The following shows `after` being used in conjunction with the [`slice` function][slice]: + +``` +{{ $data := slice "one" "two" "three" "four" }} +{{ range after 2 $data }} + {{ . }} +{{ end }} +→ ["three", "four"] +``` + +## Example of `after` with `first`: 2nd–4th Most Recent Articles + +You can use `after` in combination with the [`first` function][] and Hugo's [powerful sorting methods][lists]. Let's assume you have a list page at `example.com/articles`. You have 10 articles, but you want your templating for the [list/section page][] to show only two rows: + +1. The top row is titled "Featured" and shows only the most recently published article (i.e. by `publishdate` in the content files' front matter). +2. The second row is titled "Recent Articles" and shows only the 2nd- to 4th-most recently published articles. + +{{< code file="layouts/section/articles.html" download="articles.html" >}} +{{ define "main" }} +<section class="row featured-article"> + <h2>Featured Article</h2> + {{ range first 1 .Pages.ByPublishDate.Reverse }} + <header> + <h3><a href="{{.Permalink}}">{{.Title}}</a></h3> + </header> + <p>{{.Description}}</p> + {{ end }} +</section> +<div class="row recent-articles"> + <h2>Recent Articles</h2> + {{ range first 3 (after 1 .Pages.ByPublishDate.Reverse) }} + <section class="recent-article"> + <header> + <h3><a href="{{.Permalink}}">{{.Title}}</a></h3> + </header> + <p>{{.Description}}</p> + </section> + {{ end }} +</div> +{{ end }} +{{< /code >}} + +[`first` function]: /functions/first/ +[list/section page]: /templates/section-templates/ +[lists]: /templates/lists/#order-content +[slice]: /functions/slice/ diff --git a/docs/content/en/functions/anchorize.md b/docs/content/en/functions/anchorize.md new file mode 100644 index 000000000..b5bd22e07 --- /dev/null +++ b/docs/content/en/functions/anchorize.md @@ -0,0 +1,27 @@ +--- +title: anchorize +description: Takes a string and sanitizes it the same way as the [`defaultMarkdownHandler`](https://gohugo.io/getting-started/configuration-markup#configure-markup) does for markdown headers. +date: 2018-10-13 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [markdown,strings] +signature: ["anchorize INPUT"] +hugoversion: "0.39" +workson: [] +relatedfuncs: [humanize] +--- + +If [Goldmark](https://gohugo.io/getting-started/configuration-markup#goldmark) is set as `defaultMarkdownHandler`, the sanitizing logic adheres to the setting [`markup.goldmark.parser.autoHeadingIDType`](https://gohugo.io/getting-started/configuration-markup#goldmark). If [Blackfriday](https://gohugo.io/getting-started/configuration-markup#blackfriday) is set as `defaultMarkdownHandler`, this template function uses the [`SanitizedAnchorName` logic from Blackfriday](https://github.com/russross/blackfriday#sanitized-anchor-names) (the same applies when `markup.goldmark.parser.autoHeadingIDType` is set to `blackfriday`). + +Since the `defaultMarkdownHandler` and this template function use the same sanitizing logic, you can use the latter to determine the ID of a header for linking with anchor tags. + +```go-html-template +{{ anchorize "This is a header" }} --> "this-is-a-header" +{{ anchorize "This is also a header" }} --> "this-is-also----a-header" +{{ anchorize "main.go" }} --> "maingo" +{{ anchorize "Article 123" }} --> "article-123" +{{ anchorize "<- Let's try this, shall we?" }} --> "--lets-try-this-shall-we" +{{ anchorize "Hello, 世界" }} --> "hello-世界" +``` diff --git a/docs/content/en/functions/append.md b/docs/content/en/functions/append.md new file mode 100644 index 000000000..3e2fc13cc --- /dev/null +++ b/docs/content/en/functions/append.md @@ -0,0 +1,33 @@ +--- +title: append +description: "`append` appends one or more values to a slice and returns the resulting slice." +date: 2018-09-14 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [collections] +signature: ["COLLECTION | append VALUE [VALUE]...", "COLLECTION | append COLLECTION"] +workson: [] +hugoversion: "0.49" +relatedfuncs: [last,first,where,slice] +aliases: [] +--- + +An example appending single values: + +```go-html-template +{{ $s := slice "a" "b" "c" }} +{{ $s = $s | append "d" "e" }} +{{/* $s now contains a []string with elements "a", "b", "c", "d", and "e" */}} + +``` + +The same example appending a slice to a slice: + +```go-html-template +{{ $s := slice "a" "b" "c" }} +{{ $s = $s | append (slice "d" "e") }} +``` + +The `append` function works for all types, including `Pages`. diff --git a/docs/content/en/functions/apply.md b/docs/content/en/functions/apply.md new file mode 100644 index 000000000..7550069a5 --- /dev/null +++ b/docs/content/en/functions/apply.md @@ -0,0 +1,118 @@ +--- +title: apply +description: Given a map, array, or slice, `apply` returns a new slice with a function applied over it. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [advanced] +signature: ["apply COLLECTION FUNCTION [PARAM...]"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +{{< todo >}} +POTENTIAL NEW CONTENT: see apply/sequence discussion: https://discourse.gohugo.io/t/apply-printf-on-a-sequence/5722; +{{< /todo >}} + +`apply` expects at least three parameters, depending on the function being applied. + +1. The first parameter is the sequence to operate on. +2. The second parameter is the name of the function as a string, which must be the name of a valid [Hugo function][functions]. +3. After that, the parameters to the applied function are provided, with the string `"."` standing in for each element of the sequence the function is to be applied against. + +Here is an example of a content file with `names:` as a front matter field: + +``` ++++ +names: [ "Derek Perkins", "Joe Bergevin", "Tanner Linsley" ] ++++ +``` + +You can then use `apply` as follows: + +``` +{{ apply .Params.names "urlize" "." }} +``` + +Which will result in the following: + +``` +"derek-perkins", "joe-bergevin", "tanner-linsley" +``` + +This is *roughly* equivalent to using the following with [range][]: + +``` +{{ range .Params.names }}{{ . | urlize }}{{ end }} +``` + +However, it is not possible to provide the output of a range to the [`delimit` function][delimit], so you need to `apply` it. + +If you have `post-tag-list.html` and `post-tag-link.html` as [partials][], you *could* use the following snippets, respectively: + +{{< code file="layouts/partials/post-tag-list.html" copy="false" >}} +{{ with .Params.tags }} +<div class="tags-list"> + Tags: + {{ $len := len . }} + {{ if eq $len 1 }} + {{ partial "post-tag-link.html" (index . 0) }} + {{ else }} + {{ $last := sub $len 1 }} + {{ range first $last . }} + {{ partial "post-tag-link.html" . }}, + {{ end }} + {{ partial "post-tag-link.html" (index . $last) }} + {{ end }} +</div> +{{ end }} +{{< /code >}} + +{{< code file="layouts/partials/post-tag-link.html" copy="false" >}} +<a class="post-tag post-tag-{{ . | urlize }}" href="/tags/{{ . | urlize }}">{{ . }}</a> +{{< /code >}} + +This works, but the complexity of `post-tag-list.html` is fairly high. The Hugo template needs to perform special behavior for the case where there’s only one tag, and it has to treat the last tag as special. Additionally, the tag list will be rendered something like `Tags: tag1 , tag2 , tag3` because of the way that the HTML is generated and then interpreted by a browser. + +This first version of `layouts/partials/post-tag-list.html` separates all of the operations for ease of reading. The combined and DRYer version is shown next: + +``` +{{ with .Params.tags }} + <div class="tags-list"> + Tags: + {{ $sort := sort . }} + {{ $links := apply $sort "partial" "post-tag-link.html" "." }} + {{ $clean := apply $links "chomp" "." }} + {{ delimit $clean ", " }} + </div> +{{ end }} +``` + +Now in the completed version, you can sort the tags, convert the tags to links with `layouts/partials/post-tag-link.html`, [chomp][] off stray newlines, and join the tags together in a delimited list for presentation. Here is an even DRYer version of the preceding example: + +{{< code file="layouts/partials/post-tag-list.html" download="post-tag-list.html" >}} + {{ with .Params.tags }} + <div class="tags-list"> + Tags: + {{ delimit (apply (apply (sort .) "partial" "post-tag-link.html" ".") "chomp" ".") ", " }} + </div> + {{ end }} +{{< /code >}} + +{{% note %}} +`apply` does not work when receiving the sequence as an argument through a pipeline. +{{% /note %}} + +[chomp]: /functions/chomp/ "See documentation for the chomp function" +[delimit]: /functions/delimit/ "See documentation for the delimit function" +[functions]: /functions/ "See the full list of Hugo functions to see what can be passed as an argument to the apply function." +[partials]: /templates/partials/ +[range]: /functions/range/ "Learn the importance of the range function, a fundamental keyword in both Hugo templates and the Go programming language." diff --git a/docs/content/en/functions/base64.md b/docs/content/en/functions/base64.md new file mode 100644 index 000000000..54ca0440c --- /dev/null +++ b/docs/content/en/functions/base64.md @@ -0,0 +1,50 @@ +--- +title: base64 +description: "`base64Encode` and `base64Decode` let you easily decode content with a base64 encoding and vice versa through pipes." +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +relatedfuncs: [] +signature: ["base64Decode INPUT", "base64Encode INPUT"] +workson: [] +hugoversion: +deprecated: false +draft: false +aliases: [] +--- + +An example: + +{{< code file="base64-input.html" >}} +<p>Hello world = {{ "Hello world" | base64Encode }}</p> +<p>SGVsbG8gd29ybGQ = {{ "SGVsbG8gd29ybGQ=" | base64Decode }}</p> +{{< /code >}} + +{{< output file="base-64-output.html" >}} +<p>Hello world = SGVsbG8gd29ybGQ=</p> +<p>SGVsbG8gd29ybGQ = Hello world</p> +{{< /output >}} + +You can also pass other data types as arguments to the template function which tries to convert them. The following will convert *42* from an integer to a string because both `base64Encode` and `base64Decode` always return a string. + +``` +{{ 42 | base64Encode | base64Decode }} +=> "42" rather than 42 +``` + +## `base64` with APIs + +Using base64 to decode and encode becomes really powerful if we have to handle +responses from APIs. + +``` +{{ $resp := getJSON "https://api.github.com/repos/gohugoio/hugo/readme" }} +{{ $resp.content | base64Decode | markdownify }} +``` + +The response of the GitHub API contains the base64-encoded version of the [README.md](https://github.com/gohugoio/hugo/blob/master/README.md) in the Hugo repository. Now we can decode it and parse the Markdown. The final output will look similar to the rendered version on GitHub. diff --git a/docs/content/en/functions/chomp.md b/docs/content/en/functions/chomp.md new file mode 100644 index 000000000..c56505c2c --- /dev/null +++ b/docs/content/en/functions/chomp.md @@ -0,0 +1,24 @@ +--- +title: chomp +toc: true +description: Removes any trailing newline characters. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [trim] +signature: ["chomp INPUT"] +workson: [] +hugoversion: +relatedfuncs: [truncate] +deprecated: false +--- + +Useful in a pipeline to remove newlines added by other processing (e.g., [`markdownify`](/functions/markdownify/)). + +``` +{{chomp "<p>Blockhead</p>\n"}} → "<p>Blockhead</p>" +``` diff --git a/docs/content/en/functions/complement.md b/docs/content/en/functions/complement.md new file mode 100644 index 000000000..a41faf524 --- /dev/null +++ b/docs/content/en/functions/complement.md @@ -0,0 +1,29 @@ +--- +title: "complement" +description: "`collections.Complement` (alias `complement`) gives the elements of a collection that are not in any of the others." +date: 2018-11-07 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [collections,intersect,union] +signature: ["COLLECTION | complement COLLECTION [COLLECTION]..." ] +hugoversion: "0.51" +aliases: [] +--- + +Example: + +```go-html-template +{{ $pages := site.RegularPages | first 50 }} +{{ $news := where $pages "Type" "news" | first 5 }} +{{ $blog := where $pages "Type" "blog" | first 5 }} +{{ $other := $pages | complement $news $blog | first 10 }} +``` + +The above is an imaginary use case for the home page where you want to display different page listings in sections/boxes on different places on the page: 5 from `news`, 5 from the `blog` and then 10 of the pages not shown in the other listings, to _complement_ them. + + + + + diff --git a/docs/content/en/functions/cond.md b/docs/content/en/functions/cond.md new file mode 100644 index 000000000..a5e534426 --- /dev/null +++ b/docs/content/en/functions/cond.md @@ -0,0 +1,31 @@ +--- +title: "cond" +date: 2017-09-08 +description: "Return one of two arguments, depending on the value of a third argument." +categories: [functions] +menu: + docs: + parent: "functions" +signature: ["cond CONTROL VAR1 VAR2"] +hugoversion: 0.27 +relatedfuncs: [default] +toc: false +draft: false +needsexamples: false +--- + +`cond` returns *VAR1* if *CONTROL* is true, or *VAR2* if it is not. + +Example: + +``` +{{ cond (eq (len $geese) 1) "goose" "geese" }} +``` + +Would emit "goose" if the `$geese` array has exactly 1 item, or "geese" otherwise. + +{{% warning %}} +Whenever you use a `cond` function, *both* variable expressions are *always* evaluated. This means that a usage like `cond false (div 1 0) 27` will throw an error because `div 1 0` will be evaluated *even though the condition is false*. + +In other words, the `cond` function does *not* provide [short-circuit evaluation](https://en.wikipedia.org/wiki/Short-circuit_evaluation) and does *not* work like a normal [ternary operator](https://en.wikipedia.org/wiki/%3F:) that will pass over the first expression if the condition returns `false`. +{{% /warning %}} diff --git a/docs/content/en/functions/countrunes.md b/docs/content/en/functions/countrunes.md new file mode 100644 index 000000000..0acef095b --- /dev/null +++ b/docs/content/en/functions/countrunes.md @@ -0,0 +1,26 @@ +--- +title: countrunes +description: Determines the number of runes in a string excluding any whitespace. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [counting, word count] +signature: ["countrunes INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +In contrast with `countwords` function, which counts every word in a string, the `countrunes` function determines the number of runes in the content and excludes any whitespace. This has specific utility if you are dealing with CJK-like languages. + +``` +{{ "Hello, 世界" | countrunes }} +<!-- outputs a content length of 8 runes. --> +``` + +[pagevars]: /variables/page/ diff --git a/docs/content/en/functions/countwords.md b/docs/content/en/functions/countwords.md new file mode 100644 index 000000000..17f0fa5c2 --- /dev/null +++ b/docs/content/en/functions/countwords.md @@ -0,0 +1,27 @@ +--- +title: countwords +description: Counts the number of words in a string. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [counting, word count] +signature: ["countwords INPUT"] +workson: [] +hugoversion: +relatedfuncs: [countrunes] +deprecated: false +--- + +The template function works similar to the [.WordCount page variable][pagevars]. + +``` +{{ "Hugo is a static site generator." | countwords }} +<!-- outputs a content length of 6 words. --> +``` + + +[pagevars]: /variables/page/ diff --git a/docs/content/en/functions/dateformat.md b/docs/content/en/functions/dateformat.md new file mode 100644 index 000000000..362efabd3 --- /dev/null +++ b/docs/content/en/functions/dateformat.md @@ -0,0 +1,55 @@ +--- +title: time.Format +description: Converts a date/time to a localized string. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [dates,time,strings] +signature: ["time.Format LAYOUT INPUT"] +workson: [] +hugoversion: +relatedfuncs: [Format,now,Unix,time] +deprecated: false +--- + +`time.Format` (alias `dateFormat`) converts either a `time.Time` object (e.g. `.Date`) or a timestamp string `INPUT` into the format specified by the `LAYOUT` string. + +```go-html-template +{{ time.Format "Monday, Jan 2, 2006" "2015-01-21" }} → "Wednesday, Jan 21, 2015" +``` + +Note that since Hugo 0.87.0, `time.Format` will return a localized string for the current language. {{< new-in "0.87.0" >}} + +The `LAYOUT` string can be either: + +* [Go’s Layout String](/functions/format/#gos-layout-string) to learn about how the `LAYOUT` string has to be formatted. There are also some useful examples. +* A custom Hugo layout identifier (see full list below) + +See the [`time` function](/functions/time/) to convert a timestamp string to a Go `time.Time` type value. + + +## Date/time formatting layouts + +{{< new-in "0.87.0" >}} + +Go's date layout strings can be hard to reason about, especially with multiple languages. Since Hugo 0.87.0 you can alternatively use some predefined layout identifiers that will output localized dates or times: + +```go-html-template +{{ .Date | time.Format ":date_long" }} +``` + +The full list of custom layouts with examples for English: + +* `:date_full` => `Wednesday, June 6, 2018` +* `:date_long` => `June 6, 2018` +* `:date_medium` => `Jun 6, 2018` +* `:date_short` => `6/6/18` + +* `:time_full` => `2:09:37 am UTC` +* `:time_long` => `2:09:37 am UTC` +* `:time_medium` => `2:09:37 am` +* `:time_short` => `2:09 am` diff --git a/docs/content/en/functions/default.md b/docs/content/en/functions/default.md new file mode 100644 index 000000000..eee00b200 --- /dev/null +++ b/docs/content/en/functions/default.md @@ -0,0 +1,92 @@ +--- +title: default +description: Allows setting a default value that can be returned if a first value is not set. +qref: "Returns a default value if a value is not set when checked." +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [defaults] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: ["default DEFAULT INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +needsexamples: false +--- + +`default` checks whether a given value is set and returns a default value if it is not. *Set* in this context means different things depending on the data type: + +* non-zero for numeric types and times +* non-zero length for strings, arrays, slices, and maps +* any boolean or struct value +* non-nil for any other types + +`default` function examples reference the following content page: + +{{< code file="content/posts/default-function-example.md" >}} +--- +title: Sane Defaults +seo_title: +date: 2017-02-18 +font: +oldparam: The default function helps make your templating DRYer. +newparam: +--- +{{< /code >}} + +`default` can be written in more than one way: + +``` +{{ index .Params "font" | default "Roboto" }} +{{ default "Roboto" (index .Params "font") }} +``` + +Both of the above `default` function calls return `Roboto`. + +A `default` value, however, does not need to be hard coded like the previous example. The `default` value can be a variable or pulled directly from the front matter using dot notation: + +{{< code file="variable-as-default-value.html" nocopy="true" >}} +{{$old := .Params.oldparam }} +<p>{{ .Params.newparam | default $old }}</p> +{{< /code >}} + +Which would return: + +``` +<p>The default function helps make your templating DRYer.</p> +``` + +And then using dot notation + +{{< code file="dot-notation-default-value.html" >}} +<title>{{ .Params.seo_title | default .Title }}</title> +{{< /code >}} + +Which would return + +{{< output file="dot-notation-default-return-value.html" >}} +<title>Sane Defaults</title> +{{< /output >}} + +The following have equivalent return values but are far less terse. This demonstrates the utility of `default`: + +Using `if`: + +{{< code file="if-instead-of-default.html" nocopy="true" >}} +<title>{{if .Params.seo_title}}{{.Params.seo_title}}{{else}}{{.Title}}{{end}}</title> +=> Sane Defaults +{{< /code >}} + +Using `with`: + +{{< code file="with-instead-of-default.html" nocopy="true" >}} +<title>{{with .Params.seo_title}}{{.}}{{else}}{{.Title}}{{end}}</title> +=> Sane Defaults +{{< /code >}} diff --git a/docs/content/en/functions/delimit.md b/docs/content/en/functions/delimit.md new file mode 100644 index 000000000..533af0523 --- /dev/null +++ b/docs/content/en/functions/delimit.md @@ -0,0 +1,62 @@ +--- +title: delimit +description: Loops through any array, slice, or map and returns a string of all the values separated by a delimiter. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [iteration] +toc: false +signature: ["delimit COLLECTION DELIMIT LAST"] +workson: [lists,taxonomies,terms] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +`delimit` called in your template takes the form of + +``` +{{ delimit array/slice/map delimiter optionallastdelimiter}} +``` + +`delimit` loops through any array, slice, or map and returns a string of all the values separated by a delimiter, the second argument in the function call. There is an optional third parameter that lets you choose a different delimiter to go between the last two values in the loop. + +To maintain a consistent output order, maps will be sorted by keys and only a slice of the values will be returned. + +The examples of `delimit` that follow all use the same front matter: + +{{< code file="delimit-example-front-matter.toml" nocopy="true" >}} ++++ +title: I love Delimit +tags: [ "tag1", "tag2", "tag3" ] ++++ +{{< /code >}} + +{{< code file="delimit-page-tags-input.html" >}} +<p>Tags: {{ delimit .Params.tags ", " }}</p> +{{< /code >}} + +{{< output file="delimit-page-tags-output.html" >}} +<p>Tags: tag1, tag2, tag3</p> +{{< /output >}} + +Here is the same example but with the optional "last" delimiter: + +{{< code file="delimit-page-tags-final-and-input.html" >}} +Tags: {{ delimit .Params.tags ", " ", and " }} +{{< /code >}} + +{{< output file="delimit-page-tags-final-and-output.html" >}} +<p>Tags: tag1, tag2, and tag3</p> +{{< /output >}} + + +[lists]: /templates/lists/ +[taxonomies]: /templates/taxonomy-templates/#taxonomy-list-templates +[terms]: /templates/taxonomy-templates/#terms-list-templates diff --git a/docs/content/en/functions/dict.md b/docs/content/en/functions/dict.md new file mode 100644 index 000000000..966b6af3e --- /dev/null +++ b/docs/content/en/functions/dict.md @@ -0,0 +1,52 @@ +--- +title: dict +description: Creates a dictionary from a list of key and value pairs. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [dictionary] +signature: ["dict KEY VALUE [KEY VALUE]..."] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +`dict` is especially useful for passing more than one value to a partial template. + +Note that the `key` can be either a `string` or a `string slice`. The latter is useful to create a deeply nested structure, e.g.: + +```go-text-template +{{ $m := dict (slice "a" "b" "c") "value" }} +``` + + +## Example: Using `dict` to pass multiple values to a `partial` + +The partial below creates a SVG and expects `fill`, `height` and `width` from the caller: + +**Partial definition** + +{{< code file="layouts/partials/svgs/external-links.svg" download="external-links.svg" >}} +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" +fill="{{ .fill }}" width="{{ .width }}" height="{{ .height }}" viewBox="0 0 32 32" aria-label="External Link"> +<path d="M25.152 16.576v5.696q0 2.144-1.504 3.648t-3.648 1.504h-14.848q-2.144 0-3.648-1.504t-1.504-3.648v-14.848q0-2.112 1.504-3.616t3.648-1.536h12.576q0.224 0 0.384 0.16t0.16 0.416v1.152q0 0.256-0.16 0.416t-0.384 0.16h-12.576q-1.184 0-2.016 0.832t-0.864 2.016v14.848q0 1.184 0.864 2.016t2.016 0.864h14.848q1.184 0 2.016-0.864t0.832-2.016v-5.696q0-0.256 0.16-0.416t0.416-0.16h1.152q0.256 0 0.416 0.16t0.16 0.416zM32 1.152v9.12q0 0.48-0.352 0.8t-0.8 0.352-0.8-0.352l-3.136-3.136-11.648 11.648q-0.16 0.192-0.416 0.192t-0.384-0.192l-2.048-2.048q-0.192-0.16-0.192-0.384t0.192-0.416l11.648-11.648-3.136-3.136q-0.352-0.352-0.352-0.8t0.352-0.8 0.8-0.352h9.12q0.48 0 0.8 0.352t0.352 0.8z"></path> +</svg> +{{< /code >}} + +**Partial call** + +The `fill`, `height` and `width` values can be stored in one object with `dict` and passed to the partial: + +{{< code file="layouts/_default/list.html" >}} +{{ partial "svgs/external-links.svg" (dict "fill" "#01589B" "width" 10 "height" 20 ) }} +{{< /code >}} + + + +[partials]: /templates/partials/ diff --git a/docs/content/en/functions/echoparam.md b/docs/content/en/functions/echoparam.md new file mode 100644 index 000000000..515b5c449 --- /dev/null +++ b/docs/content/en/functions/echoparam.md @@ -0,0 +1,24 @@ +--- +title: echoParam +description: Prints a parameter if it is set. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["echoParam DICTIONARY KEY"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + + +``` +{{ echoParam .Params "project_url" }} +``` diff --git a/docs/content/en/functions/emojify.md b/docs/content/en/functions/emojify.md new file mode 100644 index 000000000..20e30fafa --- /dev/null +++ b/docs/content/en/functions/emojify.md @@ -0,0 +1,31 @@ +--- +title: emojify +description: Runs a string through the Emoji emoticons processor. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings,emojis] +signature: ["emojify INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +`emoji` runs a passed string through the Emoji emoticons processor. + +See the [Emoji cheat sheet][emojis] for available emoticons. + +The `emojify` function can be called in your templates but not directly in your content files by default. For emojis in content files, set `enableEmoji` to `true` in your site's [configuration][config]. Then you can write emoji shorthand directly into your content files; e.g. <code>I :</code><code>heart</code><code>: Hugo!</code>: + +I :heart: Hugo! + + +[config]: /getting-started/configuration/ +[emojis]: https://www.webfx.com/tools/emoji-cheat-sheet/ +[sc]: /templates/shortcode-templates/ +[scsource]: https://github.com/gohugoio/hugo/tree/master/docs/layouts/shortcodes diff --git a/docs/content/en/functions/eq.md b/docs/content/en/functions/eq.md new file mode 100644 index 000000000..d342a628a --- /dev/null +++ b/docs/content/en/functions/eq.md @@ -0,0 +1,24 @@ +--- +title: eq +linktitle: eq +description: Returns the boolean truth of arg1 == arg2. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [operators,logic] +signature: ["eq ARG1 ARG2"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{ if eq .Section "blog" }}current{{ end }} +``` diff --git a/docs/content/en/functions/errorf.md b/docs/content/en/functions/errorf.md new file mode 100644 index 000000000..41ea2f192 --- /dev/null +++ b/docs/content/en/functions/errorf.md @@ -0,0 +1,51 @@ +--- +title: errorf and warnf +description: Log ERROR or WARNING from the templates. +date: 2017-09-30 +publishdate: 2017-09-30 +lastmod: 2017-09-30 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings, log, error] +signature: ["errorf FORMAT INPUT"] +workson: [] +hugoversion: +relatedfuncs: [printf] +deprecated: false +--- + +`errorf` or `warnf` will evaluate a format string, then output the result to the ERROR or WARNING log (and only once per error message to avoid flooding the log). + +Any ERROR will also cause the build to fail (the `hugo` command will `exit -1`). + +Both functions return an empty string, so the messages are only printed to the console. + +``` +{{ errorf "Failed to handle page %q" .Path }} +``` + +``` +{{ warnf "You should update the shortcodes in %q" .Path }} +``` + +Note that `errorf`, `erroridf`, and `warnf` support all the formatting verbs of the [fmt](https://golang.org/pkg/fmt/) package. + +## Suppress errors + +Sometimes it may make sense to let the user suppress an ERROR and make the build succeed. + +You can do this by using the `erroridf` function. This functions takes an error ID as the first argument. + +``` +{{ erroridf "my-custom-error" "You should consider fixing this." }} +``` + +This will produce: + +``` +ERROR 2021/06/07 17:47:38 You should consider fixing this. +If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: +ignoreErrors = ["my-custom-error"] +``` diff --git a/docs/content/en/functions/fileExists.md b/docs/content/en/functions/fileExists.md new file mode 100644 index 000000000..2175453de --- /dev/null +++ b/docs/content/en/functions/fileExists.md @@ -0,0 +1,42 @@ +--- +title: "fileExists" +linktitle: "fileExists" +date: 2017-08-31T22:38:22+02:00 +description: Checks for file or directory existence. +publishdate: 2017-08-31T22:38:22+02:00 +lastmod: 2021-11-26 +categories: [functions] +menu: + docs: + parent: "functions" +signature: ["os.FileExists PATH","fileExists PATH"] +workson: [] +hugoversion: +relatedfuncs: ['os.ReadDir','os.ReadFile','os.Stat'] +deprecated: false +aliases: [] +--- +The `os.FileExists` function attempts to resolve the path relative to the root of your project directory. If a matching file or directory is not found, it will attempt to resolve the path relative to the [`contentDir`]({{< relref "getting-started/configuration#contentdir">}}). A leading path separator (`/`) is optional. + +With this directory structure: + +```text +content/ +├── about.md +├── contact.md +└── news/ + ├── article-1.md + └── article-2.md +``` + +The function returns these values: + +```go-html-template +{{ os.FileExists "content" }} --> true +{{ os.FileExists "content/news" }} --> true +{{ os.FileExists "content/news/article-1" }} --> false +{{ os.FileExists "content/news/article-1.md" }} --> true +{{ os.FileExists "news" }} --> true +{{ os.FileExists "news/article-1" }} --> false +{{ os.FileExists "news/article-1.md" }} --> true +``` diff --git a/docs/content/en/functions/findRe.md b/docs/content/en/functions/findRe.md new file mode 100644 index 000000000..b6375be9c --- /dev/null +++ b/docs/content/en/functions/findRe.md @@ -0,0 +1,44 @@ +--- +title: findRE +description: Returns a list of strings that match the regular expression. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [regex] +signature: ["findRE PATTERN INPUT [LIMIT]"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +By default all matches will be included. The number of matches can be limited with an optional third parameter. + +The example below returns a list of all second level headers (`<h2>`) in the content: + +``` +{{ findRE "<h2.*?>(.|\n)*?</h2>" .Content }} +``` + +You can limit the number of matches in the list with a third parameter. The following example shows how to limit the returned value to just one match (or none, if there are no matched substrings): + +``` +{{ findRE "<h2.*?>(.|\n)*?</h2>" .Content 1 }} + <!-- returns ["<h2 id="#foo">Foo</h2>"] --> +``` + +{{% note %}} +Hugo uses Go's [Regular Expression package](https://golang.org/pkg/regexp/), which is the same general syntax used by Perl, Python, and other languages but with a few minor differences for those coming from a background in PCRE. For a full syntax listing, see the [GitHub wiki for re2](https://github.com/google/re2/wiki/Syntax). + +If you are just learning RegEx, or at least Go's flavor, you can practice pattern matching in the browser at <https://regex101.com/>. +{{% /note %}} + +[partials]: /templates/partials/ +[`plainify`]: /functions/plainify/ +[toc]: /content-management/toc/ +[`urlize`]: /functions/urlize diff --git a/docs/content/en/functions/first.md b/docs/content/en/functions/first.md new file mode 100644 index 000000000..98d162617 --- /dev/null +++ b/docs/content/en/functions/first.md @@ -0,0 +1,53 @@ +--- +title: first +linktitle: first +description: "Slices an array to only the first _N_ elements." +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [iteration] +signature: ["first LIMIT COLLECTION"] +workson: [lists,taxonomies,terms,groups] +hugoversion: +relatedfuncs: [after,last] +deprecated: false +aliases: [] +--- + +`first` works in a similar manner to the [`limit` keyword in +SQL][limitkeyword]. It reduces the array to only the `first N` +elements. It takes the array and number of elements as input. + +`first` takes two arguments: +1. `number of elements` +2. `array` *or* `slice of maps or structs` + +{{< code file="layout/_default/section.html" >}} +{{ range first 10 .Pages }} + {{ .Render "summary" }} +{{ end }} +{{< /code >}} + +*Note: Exclusive to `first`, LIMIT can be '0' to return an empty array.* + +## `first` and `where` Together + +Using `first` and [`where`][wherefunction] together can be very +powerful. Below snippet gets a list of posts only from [**main +sections**][mainsections], sorts it by the `title` parameter, and then +ranges through only the first 5 posts in that list: + +{{< code file="first-and-where-together.html" >}} +{{ range first 5 (where site.RegularPages "Type" "in" site.Params.mainSections).ByTitle }} + {{ .Content }} +{{ end }} +{{< /code >}} + + +[limitkeyword]: https://www.techonthenet.com/sql/select_limit.php +[wherefunction]: /functions/where/ +[mainsections]: /functions/where/#mainsections diff --git a/docs/content/en/functions/float.md b/docs/content/en/functions/float.md new file mode 100644 index 000000000..1c589e317 --- /dev/null +++ b/docs/content/en/functions/float.md @@ -0,0 +1,25 @@ +--- +title: float +linktitle: float +description: Creates a `float` from the argument passed into the function. +date: 2017-09-28 +publishdate: 2017-09-28 +lastmod: 2017-09-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings,floats] +signature: ["float INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +Useful for turning strings into floating point numbers. + +``` +{{ float "1.23" }} → 1.23 +``` diff --git a/docs/content/en/functions/format.md b/docs/content/en/functions/format.md new file mode 100644 index 000000000..199030782 --- /dev/null +++ b/docs/content/en/functions/format.md @@ -0,0 +1,126 @@ +--- +title: .Format +description: Formats built-in Hugo dates---`.Date`, `.PublishDate`, and `.Lastmod`---according to Go's layout string. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [dates,time] +signature: [".Format FORMAT"] +workson: [times] +hugoversion: +relatedfuncs: [dateFormat,now,Unix,time] +deprecated: false +aliases: [] +toc: true +--- + +`.Format` will format date values defined in your front matter and can be used as a property on the following [page variables][pagevars]: + +* `.PublishDate` +* `.Date` +* `.Lastmod` + +Assuming a key-value of `date: 2017-03-03` in a content file's front matter, your can run the date through `.Format` followed by a layout string for your desired output at build time: + +``` +{{ .PublishDate.Format "January 2, 2006" }} => March 3, 2017 +``` + +For formatting *any* string representations of dates defined in your front matter, see the [`dateFormat` function][dateFormat], which will still leverage the Go layout string explained below but uses a slightly different syntax. + +## Go's Layout String + +Hugo templates [format your dates][time] via layout strings that point to a specific reference time: + +``` +Mon Jan 2 15:04:05 MST 2006 +``` + +While this may seem arbitrary, the numerical value of `MST` is `07`, thus making the layout string a sequence of numbers. + +Here is a visual explanation [taken directly from the Go docs][gdex]: + +``` + Jan 2 15:04:05 2006 MST +=> 1 2 3 4 5 6 -7 +``` + +### Hugo Date and Time Templating Reference + +The following examples show the layout string followed by the rendered output. + +The examples were rendered and tested in [CST][] and all point to the same field in a content file's front matter: + +``` +date: 2017-03-03T14:15:59-06:00 +``` + +`.Date` (i.e. called via [page variable][pagevars]) +: **Returns**: `2017-03-03 14:15:59 -0600 CST` + +`"Monday, January 2, 2006"` +: **Returns**: `Friday, March 3, 2017` + +`"Mon Jan 2 2006"` +: **Returns**: `Fri Mar 3 2017` + +`"January 2006"` +: **Returns**: `March 2017` + +`"2006-01-02"` +: **Returns**: `2017-03-03` + +`"Monday"` +: **Returns**: `Friday` + +`"02 Jan 06 15:04 MST"` (RFC822) +: **Returns**: `03 Mar 17 14:15 CST` + +`"02 Jan 06 15:04 -0700"` (RFC822Z) +: **Returns**: `03 Mar 17 14:15 -0600` + +`"Mon, 02 Jan 2006 15:04:05 MST"` (RFC1123) +: **Returns**: `Fri, 03 Mar 2017 14:15:59 CST` + +`"Mon, 02 Jan 2006 15:04:05 -0700"` (RFC1123Z) +: **Returns**: `Fri, 03 Mar 2017 14:15:59 -0600` + +More examples can be found in Go's [documentation for the time package][timeconst]. + +### Cardinal Numbers and Ordinal Abbreviations + +Spelled-out cardinal numbers (e.g. "one", "two", and "three") are not currently supported. + +Ordinal abbreviations (i.e., with shorted suffixes like "1st", "2nd", and "3rd") are not currently directly supported. By using `{{.Date.Format "Jan 2nd 2006"}}`, Hugo assumes you want to append `nd` as a string to the day of the month. However, you can chain functions together to create something like this: + +``` +{{ .Date.Format "2" }}{{ if in (slice 1 21 31) .Date.Day}}st{{ else if in (slice 2 22) .Date.Day}}nd{{ else if in (slice 3 23) .Date.Day}}rd{{ else }}th{{ end }} of {{ .Date.Format "January 2006" }} +``` + +This will output: + +``` +5th of March 2017 +``` + + +### Use `.Local` and `.UTC` + +In conjunction with the [`dateFormat` function][dateFormat], you can also convert your dates to `UTC` or to local timezones: + +`{{ dateFormat "02 Jan 06 15:04 MST" .Date.UTC }}` +: **Returns**: `03 Mar 17 20:15 UTC` + +`{{ dateFormat "02 Jan 06 15:04 MST" .Date.Local }}` +: **Returns**: `03 Mar 17 14:15 CST` + +[CST]: https://en.wikipedia.org/wiki/Central_Time_Zone +[dateFormat]: /functions/dateformat/ +[gdex]: https://golang.org/pkg/time/#example_Time_Format +[pagevars]: /variables/page/ +[time]: https://golang.org/pkg/time/ +[timeconst]: https://golang.org/pkg/time/#ANSIC diff --git a/docs/content/en/functions/ge.md b/docs/content/en/functions/ge.md new file mode 100644 index 000000000..c7256c0e3 --- /dev/null +++ b/docs/content/en/functions/ge.md @@ -0,0 +1,24 @@ +--- +title: ge +linktitle: ge +description: Returns the boolean truth of arg1 >= arg2. +date: 2017-07-26 +publishdate: 2017-07-26 +lastmod: 2017-07-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [operators,logic] +signature: ["ge ARG1 ARG2"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{ if ge 10 5 }}true{{ end }} +``` diff --git a/docs/content/en/functions/get.md b/docs/content/en/functions/get.md new file mode 100644 index 000000000..c5b75c7fd --- /dev/null +++ b/docs/content/en/functions/get.md @@ -0,0 +1,30 @@ +--- +title: .Get +description: Accesses positional and ordered parameters in shortcode declaration. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [shortcodes] +signature: [".Get INDEX", ".Get KEY"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +needsexample: true +--- + + +`.Get` is specifically used when creating your own [shortcode template][sc], to access the [positional and named](/templates/shortcode-templates/#positional-vs-named-parameters) parameters passed to it. When used with a numeric INDEX, it queries positional parameters (starting with 0). With a string KEY, it queries named parameters. + +When accessing a named parameter that does not exist, `.Get` returns an empty string instead of interrupting the build. The same goes with positional parameters in hugo version 0.40 and after. This allows you to chain `.Get` with `if`, `with`, `default` or `cond` to check for parameter existence. For example, you may now use: + +``` +{{ $quality := default "100" (.Get 1) }} +``` + +[sc]: /templates/shortcode-templates/ diff --git a/docs/content/en/functions/getenv.md b/docs/content/en/functions/getenv.md new file mode 100644 index 000000000..f7f71d35c --- /dev/null +++ b/docs/content/en/functions/getenv.md @@ -0,0 +1,43 @@ +--- +title: getenv +description: Returns the value of an environment variable, or an empty string if the environment variable is not set. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2021-11-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["os.Getenv VARIABLE", "getenv VARIABLE"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- +Examples: + +```go-html-template +{{ os.Getenv "HOME" }} --> /home/victor +{{ os.Getenv "USER" }} --> victor +``` + +You can pass values when building your site: + +```bash +MY_VAR1=foo MY_VAR2=bar hugo + +OR + +export MY_VAR1=foo +export MY_VAR2=bar +hugo +``` + +And then retrieve the values within a template: + +```go-html-template +{{ os.Getenv "MY_VAR1" }} --> foo +{{ os.Getenv "MY_VAR2" }} --> bar +``` diff --git a/docs/content/en/functions/group.md b/docs/content/en/functions/group.md new file mode 100644 index 000000000..203498cb1 --- /dev/null +++ b/docs/content/en/functions/group.md @@ -0,0 +1,31 @@ +--- +title: group +description: "`group` groups a list of pages." +date: 2018-09-14 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [collections] +signature: ["PAGES | group KEY"] +hugoversion: "0.49" +--- + +{{< code file="layouts/partials/groups.html" >}} +{{ $new := .Site.RegularPages | first 10 | group "New" }} +{{ $old := .Site.RegularPages | last 10 | group "Old" }} +{{ $groups := slice $new $old }} +{{ range $groups }} +<h3>{{ .Key }}{{/* Prints "New", "Old" */}}</h3> +<ul> + {{ range .Pages }} + <li> + <a href="{{ .Permalink }}">{{ .Title }}</a> + <div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div> + </li> + {{ end }} +</ul> +{{ end }} +{{< /code >}} + +The page group you get from `group` is of the same type you get from the built-in [group methods](/templates/lists#group-content) in Hugo. The above example can even be [paginated](/templates/pagination/#list-paginator-pages). diff --git a/docs/content/en/functions/gt.md b/docs/content/en/functions/gt.md new file mode 100644 index 000000000..91203f890 --- /dev/null +++ b/docs/content/en/functions/gt.md @@ -0,0 +1,24 @@ +--- +title: gt +linktitle: gt +description: Returns the boolean truth of arg1 > arg2. +date: 2017-07-26 +publishdate: 2017-07-26 +lastmod: 2017-07-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [operators,logic] +signature: ["gt ARG1 ARG2"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{ if gt 10 5 }}true{{ end }} +``` diff --git a/docs/content/en/functions/hasPrefix.md b/docs/content/en/functions/hasPrefix.md new file mode 100644 index 000000000..99d5ba819 --- /dev/null +++ b/docs/content/en/functions/hasPrefix.md @@ -0,0 +1,21 @@ +--- +title: hasprefix +linktitle: hasPrefix +description: Tests whether a string begins with prefix. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["hasPrefix STRING PREFIX"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +* `{{ hasPrefix "Hugo" "Hu" }}` → true diff --git a/docs/content/en/functions/haschildren.md b/docs/content/en/functions/haschildren.md new file mode 100644 index 000000000..1deeb7277 --- /dev/null +++ b/docs/content/en/functions/haschildren.md @@ -0,0 +1,22 @@ +--- +title: .HasChildren +description: +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [menus] +toc: +signature: ["HasChildren"] +workson: [menus] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: true +aliases: [] +--- + +Used in [menu templates](/templates/menu-templates/). diff --git a/docs/content/en/functions/hasmenucurrent.md b/docs/content/en/functions/hasmenucurrent.md new file mode 100644 index 000000000..dbd4aa418 --- /dev/null +++ b/docs/content/en/functions/hasmenucurrent.md @@ -0,0 +1,28 @@ +--- +title: .HasMenuCurrent +description: +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [menus] +signature: ["PAGE.HasMenuCurrent MENU MENUENTRY"] +workson: [menus] +hugoversion: +relatedfuncs: ["IsMenuCurrent"] +deprecated: false +toc: false +draft: false +aliases: [] +--- + +`.HasMenuCurrent` is a method in `Page` object returning a _boolean_ value. It +returns `true` if the PAGE is the same object as the `.Page` in one of the +**children menu entries** under MENUENTRY in a given MENU. + +{{< new-in "0.86.0" >}} If MENUENTRY's `.Page` is a [section](/content-management/sections/) then, from Hugo `0.86.0`, this method also returns true for any descendant of that section.. + +You can find its example use in [menu templates](/templates/menu-templates/). diff --git a/docs/content/en/functions/highlight.md b/docs/content/en/functions/highlight.md new file mode 100644 index 000000000..1643fe075 --- /dev/null +++ b/docs/content/en/functions/highlight.md @@ -0,0 +1,104 @@ +--- +title: highlight +linktitle: highlight +description: Renders code with a syntax highlighter. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2021-12-06 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [highlighting,code blocks,syntax] +signature: ["transform.Highlight INPUT LANG [OPTIONS]","highlight INPUT LANG [OPTIONS]"] +relatedfuncs: [] +deprecated: false +toc: true +--- +The `highlight` function uses the [Chroma] syntax highlighter, supporting over 200 languages with more than 40 available styles. + +## Parameters + +INPUT +: The code to highlight. + +LANG +: The language of the code to highlight. Choose from one of the [supported languages]. Case-insensitive. + +OPTIONS +: An optional, comma-separated list of zero or more [options]. Set default values in [site configuration]. + +## Options + +lineNos +: Boolean. Default is `false`.\ +Display a number at the beginning of each line. + +lineNumbersInTable +: Boolean. Default is `true`.\ +Render the highlighted code in an HTML table with two cells. The left table cell contains the line numbers. The right table cell contains the code, allowing a user to select and copy the code without line numbers. Irrelevant if `lineNos` is false. + +anchorLineNos +: Boolean. Default is `false`.\ +Render each line number as an HTML anchor element, and set the `id` attribute of the surrounding `<span>` to the line number. Irrelevant if `lineNos` is false. + +lineAnchors +: String. Default is `""`.\ +When rendering a line number as an HTML anchor element, prepend this value to the `id` attribute of the surrounding `<span>`. This provides unique `id` attributes when a page contains two or more code blocks. Irrelevant if `lineNos` or `anchorLineNos` is false. + +lineNoStart +: Integer. Default is `1`.\ +The number to display at the beginning of the first line. Irrelevant if `lineNos` is false. + +hl_Lines +: String. Default is `""`.\ +A space-separated list of lines to emphasize within the highlighted code. To emphasize lines 2, 3, 4, and 7, set this value to `2-4 7`. This option is independent of the `lineNoStart` option. + +style +: String. Default is `monokai`.\ +The CSS styles to apply to the highlighted code. See the [style gallery] for examples. Case-sensitive. + +noClasses +: Boolean. Default is `true`.\ +Use inline CSS styles instead of an external CSS file. To use an external CSS file, set this value to `false` and [generate the file with the hugo client][hugo client]. + +tabWidth +: Integer. Default is `4`.\ +Substitute this number of spaces for each tab character in your highlighted code. + +guessSyntax +: Boolean. Default is `false`.\ +If the `LANG` parameter is blank or an unrecognized language, auto-detect the language if possible, otherwise use a fallback language. + +{{% note %}} +Instead of specifying both `lineNos` and `lineNumbersInTable`, you can use the following shorthand notation: + +`lineNos=inline` +: equivalent to `lineNos=true` and `lineNumbersInTable=false` + +`lineNos=table` +: equivalent to `lineNos=true` and `lineNumbersInTable=true` +{{% /note %}} + +## Examples + +```go-html-template +{{ $input := `fmt.Println("Hello World!")` }} +{{ transform.Highlight $input "go" }} + +{{ $input := `console.log('Hello World!');` }} +{{ $lang := "js" }} +{{ transform.Highlight $input $lang "lineNos=table, style=api" }} + +{{ $input := `echo "Hello World!"` }} +{{ $lang := "bash" }} +{{ $options := slice "lineNos=table" "style=dracula" }} +{{ transform.Highlight $input $lang (delimit $options ",") }} +``` + +[Chroma]: https://github.com/alecthomas/chroma +[hugo client]: {{< relref "commands/hugo_gen_chromastyles" >}} +[options]: {{< relref "#options" >}} +[site configuration]: {{< relref "getting-started/configuration-markup#highlight">}} +[style gallery]: https://xyproto.github.io/splash/docs/ +[supported languages]: {{< relref "content-management/syntax-highlighting#list-of-chroma-highlighting-languages" >}} diff --git a/docs/content/en/functions/hmac.md b/docs/content/en/functions/hmac.md new file mode 100644 index 000000000..b906e5abb --- /dev/null +++ b/docs/content/en/functions/hmac.md @@ -0,0 +1,34 @@ +--- +title: hmac +linktitle: hmac +description: Returns a cryptographic hash that uses a key to sign a message. +date: 2020-05-29 +publishdate: 2020-05-29 +lastmod: 2020-05-29 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [hmac,checksum] +signature: ["crypto.HMAC HASH_TYPE KEY MESSAGE [ENCODING]","hmac HASH_TYPE KEY MESSAGE [ENCODING]" ] +workson: [] +hugoversion: +relatedfuncs: [hmac] +deprecated: false +aliases: [] +--- + +Set the `HASH_TYPE` argument to `md5`, `sha1`, `sha256`, or `sha512`. + +Set the optional `ENCODING` argument to either `hex` (default) or `binary`. + +```go-html-template +{{ hmac "sha256" "Secret key" "Secret message" }} +5cceb491f45f8b154e20f3b0a30ed3a6ff3027d373f85c78ffe8983180b03c84 + +{{ hmac "sha256" "Secret key" "Secret message" "hex" }} +5cceb491f45f8b154e20f3b0a30ed3a6ff3027d373f85c78ffe8983180b03c84 + +{{ hmac "sha256" "Secret key" "Secret message" "binary" | base64Encode }} +XM60kfRfixVOIPOwow7Tpv8wJ9Nz+Fx4/+iYMYCwPIQ= +``` diff --git a/docs/content/en/functions/htmlEscape.md b/docs/content/en/functions/htmlEscape.md new file mode 100644 index 000000000..652492c72 --- /dev/null +++ b/docs/content/en/functions/htmlEscape.md @@ -0,0 +1,25 @@ +--- +title: htmlEscape +linktitle: +description: Returns the given string with the reserved HTML codes escaped. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings, html] +signature: ["htmlEscape INPUT"] +workson: [] +hugoversion: +relatedfuncs: [htmlUnescape] +deprecated: false +aliases: [] +--- + +In the result `&` becomes `&` and so on. It escapes only: `<`, `>`, `&`, `'` and `"`. + +``` +{{ htmlEscape "Hugo & Caddy > WordPress & Apache" }} → "Hugo & Caddy > WordPress & Apache" +``` diff --git a/docs/content/en/functions/htmlUnescape.md b/docs/content/en/functions/htmlUnescape.md new file mode 100644 index 000000000..9533fde90 --- /dev/null +++ b/docs/content/en/functions/htmlUnescape.md @@ -0,0 +1,27 @@ +--- +title: htmlUnescape +linktitle: htmlUnescape +description: Returns the given string with HTML escape codes un-escaped. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["htmlUnescape INPUT"] +workson: [] +hugoversion: +relatedfuncs: [htmlEscape] +deprecated: false +aliases: [] +--- + +`htmlUnescape` returns the given string with HTML escape codes un-escaped. + +Remember to pass the output of this to `safeHTML` if fully un-escaped characters are desired. Otherwise, the output will be escaped again as normal. + +``` +{{ htmlUnescape "Hugo & Caddy > WordPress & Apache" }} → "Hugo & Caddy > WordPress & Apache" +``` diff --git a/docs/content/en/functions/hugo.md b/docs/content/en/functions/hugo.md new file mode 100644 index 000000000..a495eae0a --- /dev/null +++ b/docs/content/en/functions/hugo.md @@ -0,0 +1,115 @@ +--- +title: hugo +linktitle: hugo +description: The `hugo` function provides easy access to Hugo-related data. +date: 2019-01-31 +publishdate: 2019-01-31 +keywords: [] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: ["hugo"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +`hugo` returns an instance that contains the following functions: + +hugo.Generator +: `<meta>` tag for the version of Hugo that generated the site. `hugo.Generator` outputs a *complete* HTML tag; e.g. `<meta name="generator" content="Hugo 0.63.2" />` + +hugo.Version +: the current version of the Hugo binary you are using e.g. `0.63.2` + + +`hugo` returns an instance that contains the following functions: + +hugo.Environment +: the current running environment as defined through the `--environment` cli tag + +hugo.CommitHash +: the git commit hash of the current Hugo binary e.g. `0e8bed9ccffba0df554728b46c5bbf6d78ae5247` + +hugo.BuildDate +: the compile date of the current Hugo binary formatted with RFC 3339 e.g. `2002-10-02T10:00:00-05:00` + +hugo.IsExtended {{< new-in "0.83.0" >}} +: whether this is the extended Hugo binary. + +hugo.IsProduction +: returns true if `hugo.Environment` is set to the production environment + +{{% note "Use the Hugo Generator Tag" %}} +We highly recommend using `hugo.Generator` in your website's `<head>`. `hugo.Generator` is included by default in all themes hosted on [themes.gohugo.io](https://themes.gohugo.io). The generator tag allows the Hugo team to track the usage and popularity of Hugo. +{{% /note %}} + +hugo.Deps +: See [hugo.Deps](#hugodeps) + + +## hugo.Deps + +{{< new-in "0.92.0" >}} + +`hugo.Deps` returns a list of dependencies for a project (either Hugo Modules or local theme components). + +Each dependency contains: + +Path (string) +: Returns the path to this module. This will either be the module path, e.g. "github.com/gohugoio/myshortcodes", or the path below your /theme folder, e.g. "mytheme". + +Version (string) +: The module version. + +Vendor (bool) +: Whether this dependency is vendored. + +Time (time.Time) +: Time version was created. + +Owner +: In the dependency tree, this is the first module that defines this module as a dependency. + +Replace (*Dependency) +: Replaced by this dependency. + +An example table listing the dependencies: + +```html + <h2>Dependencies</h2> +<table class="table table-dark"> + <thead> + <tr> + <th scope="col">#</th> + <th scope="col">Owner</th> + <th scope="col">Path</th> + <th scope="col">Version</th> + <th scope="col">Time</th> + <th scope="col">Vendor</th> + </tr> + </thead> + <tbody> + {{ range $index, $element := hugo.Deps }} + <tr> + <th scope="row">{{ add $index 1 }}</th> + <td>{{ with $element.Owner }}{{.Path }}{{ end }}</td> + <td> + {{ $element.Path }} + {{ with $element.Replace}} + => {{ .Path }} + {{ end }} + </td> + <td>{{ $element.Version }}</td> + <td>{{ with $element.Time }}{{ . }}{{ end }}</td> + <td>{{ $element.Vendor }}</td> + </tr> + {{ end }} + </tbody> +</table> +```
\ No newline at end of file diff --git a/docs/content/en/functions/humanize.md b/docs/content/en/functions/humanize.md new file mode 100644 index 000000000..18a087591 --- /dev/null +++ b/docs/content/en/functions/humanize.md @@ -0,0 +1,29 @@ +--- +title: humanize +linktitle: +description: Returns the humanized version of an argument with the first letter capitalized. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings,casing] +signature: ["humanize INPUT"] +workson: [] +hugoversion: +relatedfuncs: [anchorize] +deprecated: false +aliases: [] +--- + +If the input is either an int64 value or the string representation of an integer, humanize returns the number with the proper ordinal appended. + + +``` +{{humanize "my-first-post"}} → "My first post" +{{humanize "myCamelPost"}} → "My camel post" +{{humanize "52"}} → "52nd" +{{humanize 103}} → "103rd" +``` diff --git a/docs/content/en/functions/i18n.md b/docs/content/en/functions/i18n.md new file mode 100644 index 000000000..7d88292b9 --- /dev/null +++ b/docs/content/en/functions/i18n.md @@ -0,0 +1,33 @@ +--- +title: i18n +linktitle: i18n +description: Translates a piece of content based on your i18n configuration files. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [internationalization,i18n,multilingual] +signature: ["i18n KEY", "T KEY"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +This translates a piece of content based on your `i18n/en-US.yaml` (and similar) files. You can use the [go-i18n](https://github.com/nicksnyder/go-i18n) tools to manage your translations. The translations can exist in both the theme and at the root of your repository. + +``` +{{ i18n "translation_id" }} +``` + +{{% note "Alias `T`" %}} +`T` is an alias to `i18n`. E.g. `{{ T "translation_id" }}`. +{{% /note %}} + +For more information about string translations, see [Translation of Strings in Multilingual Mode][multistrings]. + +[multistrings]: /content-management/multilingual/#translation-of-strings diff --git a/docs/content/en/functions/images/index.md b/docs/content/en/functions/images/index.md new file mode 100644 index 000000000..92c6ff0da --- /dev/null +++ b/docs/content/en/functions/images/index.md @@ -0,0 +1,229 @@ +--- +title: Image Filters +description: The images namespace provides a list of filters and other image related functions. +date: 2017-02-01 +categories: [functions] +aliases: [/functions/imageconfig/] +menu: + docs: + parent: "functions" +keywords: [images] +toc: true +--- + +See [images.Filter](#filter) for how to apply these filters to an image. + +## Overlay + +{{< new-in "0.80.0" >}} + +{{% funcsig %}} +images.Overlay SRC X Y +{{% /funcsig %}} + +Overlay creates a filter that overlays the source image at position x y, e.g: + + +```go-html-template +{{ $logoFilter := (images.Overlay $logo 50 50 ) }} +{{ $img := $img | images.Filter $logoFilter }} +``` + +A shorter version of the above, if you only need to apply the filter once: + +```go-html-template +{{ $img := $img.Filter (images.Overlay $logo 50 50 )}} +``` + +The above will overlay `$logo` in the upper left corner of `$img` (at position `x=50, y=50`). + +## Text + +{{< new-in "0.90.0" >}} + +Using the `Text` filter, you can add text to an image. + +{{% funcsig %}} +images.Text TEXT DICT) +{{% /funcsig %}} + +The following example will add the text `Hugo rocks!` to the image with the specified color, size and position. + +```go-html-template +{{ $img := resources.Get "/images/background.png"}} +{{ $img = $img.Filter (images.Text "Hugo rocks!" (dict + "color" "#ffffff" + "size" 60 + "linespacing" 2 + "x" 10 + "y" 20 +))}} +``` + +You can load a custom font if needed. Load the font as a Hugo `Resource` and set it as an option: + +```go-html-template + +{{ $font := resources.Get "https://github.com/google/fonts/raw/main/apache/roboto/static/Roboto-Black.ttf" }} +{{ $img := resources.Get "/images/background.png"}} +{{ $img = $img.Filter (images.Text "Hugo rocks!" (dict + "font" $font +))}} +``` + + +## Brightness + +{{% funcsig %}} +images.Brightness PERCENTAGE +{{% /funcsig %}} + +Brightness creates a filter that changes the brightness of an image. +The percentage parameter must be in range (-100, 100). + +### ColorBalance + +{{% funcsig %}} +images.ColorBalance PERCENTAGERED PERCENTAGEGREEN PERCENTAGEBLUE +{{% /funcsig %}} + +ColorBalance creates a filter that changes the color balance of an image. +The percentage parameters for each color channel (red, green, blue) must be in range (-100, 500). + +## Colorize + +{{% funcsig %}} +images.Colorize HUE SATURATION PERCENTAGE +{{% /funcsig %}} + +Colorize creates a filter that produces a colorized version of an image. +The hue parameter is the angle on the color wheel, typically in range (0, 360). +The saturation parameter must be in range (0, 100). +The percentage parameter specifies the strength of the effect, it must be in range (0, 100). + +## Contrast + +{{% funcsig %}} +images.Contrast PERCENTAGE +{{% /funcsig %}} + +Contrast creates a filter that changes the contrast of an image. +The percentage parameter must be in range (-100, 100). + +## Gamma + +{{% funcsig %}} +images.Gamma GAMMA +{{% /funcsig %}} + +Gamma creates a filter that performs a gamma correction on an image. +The gamma parameter must be positive. Gamma = 1 gives the original image. +Gamma less than 1 darkens the image and gamma greater than 1 lightens it. + +## GaussianBlur + +{{% funcsig %}} +images.GaussianBlur SIGMA +{{% /funcsig %}} + +GaussianBlur creates a filter that applies a gaussian blur to an image. + +## Grayscale + +{{% funcsig %}} +images.Grayscale +{{% /funcsig %}} + +Grayscale creates a filter that produces a grayscale version of an image. + +## Hue + +{{% funcsig %}} +images.Hue SHIFT +{{% /funcsig %}} + +Hue creates a filter that rotates the hue of an image. +The hue angle shift is typically in range -180 to 180. + +## Invert + +{{% funcsig %}} +images.Invert +{{% /funcsig %}} + +Invert creates a filter that negates the colors of an image. + +## Pixelate + +{{% funcsig %}} +images.Pixelate SIZE +{{% /funcsig %}} + +Pixelate creates a filter that applies a pixelation effect to an image. + +## Saturation + +{{% funcsig %}} +images.Saturation PERCENTAGE +{{% /funcsig %}} + +Saturation creates a filter that changes the saturation of an image. + +## Sepia + +{{% funcsig %}} +images.Sepia PERCENTAGE +{{% /funcsig %}} + +Sepia creates a filter that produces a sepia-toned version of an image. + +## Sigmoid + +{{% funcsig %}} +images.Sigmoid MIDPOINT FACTOR +{{% /funcsig %}} + +Sigmoid creates a filter that changes the contrast of an image using a sigmoidal function and returns the adjusted image. +It's a non-linear contrast change useful for photo adjustments as it preserves highlight and shadow detail. + +## UnsharpMask + +{{% funcsig %}} +images.UnsharpMask SIGMA AMOUNT THRESHOLD +{{% /funcsig %}} + +UnsharpMask creates a filter that sharpens an image. +The sigma parameter is used in a gaussian function and affects the radius of effect. +Sigma must be positive. Sharpen radius roughly equals 3 * sigma. +The amount parameter controls how much darker and how much lighter the edge borders become. Typically between 0.5 and 1.5. +The threshold parameter controls the minimum brightness change that will be sharpened. Typically between 0 and 0.05. + +## Other Functions + +### Filter + +{{% funcsig %}} +IMAGE | images.Filter FILTERS... +{{% /funcsig %}} + +Can be used to apply a set of filters to an image: + +```go-html-template +{{ $img := $img | images.Filter (images.GaussianBlur 6) (images.Pixelate 8) }} +``` + +Also see the [Filter Method](/content-management/image-processing/#filter). + +### ImageConfig + +Parses the image and returns the height, width, and color model. + +{{% funcsig %}} +images.ImageConfig PATH +{{% /funcsig %}} + +```go-html-template +{{ with (imageConfig "favicon.ico") }} +favicon.ico: {{.Width}} x {{.Height}} +{{ end }} +``` diff --git a/docs/content/en/functions/in.md b/docs/content/en/functions/in.md new file mode 100644 index 000000000..7a8cb33eb --- /dev/null +++ b/docs/content/en/functions/in.md @@ -0,0 +1,32 @@ +--- +title: in +linktitle: +description: Checks if an element is in an array or slice--or a substring in a string---and returns a boolean. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["in SET ITEM"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +The elements supported are strings, integers and floats, although only float64 will match as expected. + +In addition, `in` can also check if a substring exists in a string. + +``` +{{ if in .Params.tags "Git" }}Follow me on GitHub!{{ end }} +``` + + +``` +{{ if in "this string contains a substring" "substring" }}Substring found!{{ end }} +``` diff --git a/docs/content/en/functions/index-function.md b/docs/content/en/functions/index-function.md new file mode 100644 index 000000000..6ee46b4a8 --- /dev/null +++ b/docs/content/en/functions/index-function.md @@ -0,0 +1,100 @@ +--- +title: index +linktitle: index +description: Looks up the index(es) or key(s) of the data structure passed into it. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["index COLLECTION INDEXES", "index COLLECTION KEYS"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [/functions/index/] +needsexample: true +--- + +The `index` functions returns the result of indexing its first argument by the following arguments. Each indexed item must be a map or a slice, e.g.: + +```go-text-template +{{ $slice := slice "a" "b" "c" }} +{{ index $slice 1 }} => b +{{ $map := dict "a" 100 "b" 200 }} +{{ index $map "b" }} => 200 +``` + +The function takes multiple indices as arguments, and this can be used to get nested values, e.g.: + +```go-text-template +{{ $map := dict "a" 100 "b" 200 "c" (slice 10 20 30) }} +{{ index $map "c" 1 }} => 20 +{{ $map := dict "a" 100 "b" 200 "c" (dict "d" 10 "e" 20) }} +{{ index $map "c" "e" }} => 20 +``` + +You may write multiple indices as a slice: + +```go-text-template +{{ $map := dict "a" 100 "b" 200 "c" (dict "d" 10 "e" 20) }} +{{ $slice := slice "c" "e" }} +{{ index $map $slice }} => 20 +``` + +## Example: Load Data from a Path Based on Front Matter Params + +Assume you want to add a `location = ""` field to your front matter for every article written in `content/vacations/`. You want to use this field to populate information about the location at the bottom of the article in your `single.html` template. You also have a directory in `data/locations/` that looks like the following: + +``` +. +└── data + └── locations + ├── abilene.toml + ├── chicago.toml + ├── oslo.toml + └── provo.toml +``` + +Here is an example: + +{{< code-toggle file="data/locations/oslo" >}} +website = "https://www.oslo.kommune.no" +pop_city = 658390 +pop_metro = 1717900 +{{< /code-toggle >}} + +The example we will use will be an article on Oslo, whose front matter should be set to exactly the same name as the corresponding file name in `data/locations/`: + +``` +title = "My Norwegian Vacation" +location = "oslo" +``` + +The content of `oslo.toml` can be accessed from your template using the following node path: `.Site.Data.locations.oslo`. However, the specific file you need is going to change according to the front matter. + +This is where the `index` function is needed. `index` takes 2 parameters in this use case: + +1. The node path +2. A string corresponding to the desired data; e.g.— + +``` +{{ index .Site.Data.locations “oslo” }} +``` + +The variable for `.Params.location` is a string and can therefore replace `oslo` in the example above: + +``` +{{ index .Site.Data.locations .Params.location }} +=> map[website:https://www.oslo.kommune.no pop_city:658390 pop_metro:1717900] +``` + +Now the call will return the specific file according to the location specified in the content's front matter, but you will likely want to write specific properties to the template. You can do this by continuing down the node path via dot notation (`.`): + +``` +{{ (index .Site.Data.locations .Params.location).pop_city }} +=> 658390 +``` diff --git a/docs/content/en/functions/int.md b/docs/content/en/functions/int.md new file mode 100644 index 000000000..24818cef6 --- /dev/null +++ b/docs/content/en/functions/int.md @@ -0,0 +1,50 @@ +--- +title: int +linktitle: int +description: Creates an `int` from the argument passed into the function. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings,integers] +signature: ["int INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +Useful for turning strings into numbers. + +``` +{{ int "123" }} → 123 +``` + +{{% note "Usage Note" %}} +If the input string is supposed to represent a decimal number, and if it has +leading 0's, then those 0's will have to be removed before passing the string +to the `int` function, else that string will be tried to be parsed as an octal +number representation. + +The [`strings.TrimLeft` function](/functions/strings.trimleft/) can be used for +this purpose. + +``` +{{ int ("0987" | strings.TrimLeft "0") }} +{{ int ("00987" | strings.TrimLeft "0") }} +``` + +**Explanation** + +The `int` function eventually calls the `ParseInt` function from the Go library +`strconv`. + +From its [documentation](https://golang.org/pkg/strconv/#ParseInt): + +> the base is implied by the string's prefix: base 16 for "0x", base 8 for "0", +> and base 10 otherwise. +{{% /note %}} diff --git a/docs/content/en/functions/intersect.md b/docs/content/en/functions/intersect.md new file mode 100644 index 000000000..2fe73ded8 --- /dev/null +++ b/docs/content/en/functions/intersect.md @@ -0,0 +1,36 @@ +--- +title: intersect +linktitle: intersect +description: Returns the common elements of two arrays or slices, in the same order as the first array. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [collections,intersect,union,complement,symdiff] +signature: ["intersect SET1 SET2"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- +An useful example is to use it as `AND` filters when combined with where: + +## AND filter in where query + +``` +{{ $pages := where .Site.RegularPages "Type" "not in" (slice "page" "about") }} +{{ $pages := $pages | union (where .Site.RegularPages "Params.pinned" true) }} +{{ $pages := $pages | intersect (where .Site.RegularPages "Params.images" "!=" nil) }} +``` + +The above fetches regular pages not of `page` or `about` type unless they are pinned. And finally, we exclude all pages with no `images` set in Page params. + +See [union](/functions/union) for `OR`. + + +[partials]: /templates/partials/ +[single]: /templates/single-page-templates/ diff --git a/docs/content/en/functions/ismenucurrent.md b/docs/content/en/functions/ismenucurrent.md new file mode 100644 index 000000000..51c21721b --- /dev/null +++ b/docs/content/en/functions/ismenucurrent.md @@ -0,0 +1,26 @@ +--- +title: .IsMenuCurrent +description: +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [menus] +signature: ["PAGE.IsMenuCurrent MENU MENUENTRY"] +workson: [menus] +hugoversion: +relatedfuncs: ["HasMenuCurrent"] +deprecated: false +draft: false +aliases: [] +needsexample: true +--- + +`.IsMenuCurrent` is a method in `Page` object returning a _boolean_ value. It +returns `true` if the PAGE is the same object as the `.Page` in MENUENTRY in a +given MENU. + +You can find its example use in [menu templates](/templates/menu-templates/). diff --git a/docs/content/en/functions/isset.md b/docs/content/en/functions/isset.md new file mode 100644 index 000000000..aa36f6dac --- /dev/null +++ b/docs/content/en/functions/isset.md @@ -0,0 +1,30 @@ +--- +title: isset +linktitle: isset +description: Returns true if the parameter is set. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["isset COLLECTION INDEX", "isset COLLECTION KEY"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +Takes either a slice, array, or channel and an index or a map and a key as input. + +``` +{{ if isset .Params "project_url" }} {{ index .Params "project_url" }}{{ end }} +``` + +{{% warning %}} +All site-level configuration keys are stored as lower case. Therefore, a `myParam` key-value set in your [site configuration file](/getting-started/configuration/) needs to be accessed with `{{if isset .Site.Params "myparam"}}` and *not* with `{{if isset .Site.Params "myParam"}}`. Note that you can still access the same config key with `.Site.Params.myParam` *or* `.Site.Params.myparam`, for example, when using [`with`](/functions/with). +This restriction also applies when accessing page-level front matter keys from within [shortcodes](/content-management/shortcodes/). +{{% /warning %}} diff --git a/docs/content/en/functions/jsonify.md b/docs/content/en/functions/jsonify.md new file mode 100644 index 000000000..28b90534c --- /dev/null +++ b/docs/content/en/functions/jsonify.md @@ -0,0 +1,37 @@ +--- +title: jsonify +linktitle: jsonify +description: Encodes a given object to JSON. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2020-04-13 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings,json] +signature: ["jsonify INPUT", "jsonify OPTIONS INPUT"] +workson: [] +hugoversion: +relatedfuncs: [plainify] +deprecated: false +aliases: [] +--- + +Jsonify encodes a given object to JSON. + +To customize the printing of the JSON, pass a dictionary of options as the first +argument. Supported options are "prefix" and "indent". Each JSON element in +the output will begin on a new line beginning with *prefix* followed by one or +more copies of *indent* according to the indentation nesting. + + +``` +{{ dict "title" .Title "content" .Plain | jsonify }} +{{ dict "title" .Title "content" .Plain | jsonify (dict "indent" " ") }} +{{ dict "title" .Title "content" .Plain | jsonify (dict "prefix" " " "indent" " ") }} +``` + +See also the `.PlainWords`, `.Plain`, and `.RawContent` [page variables][pagevars]. + +[pagevars]: /variables/page/ diff --git a/docs/content/en/functions/lang.Merge.md b/docs/content/en/functions/lang.Merge.md new file mode 100644 index 000000000..78d658442 --- /dev/null +++ b/docs/content/en/functions/lang.Merge.md @@ -0,0 +1,37 @@ +--- +title: lang.Merge +description: "Merge missing translations from other languages." +date: 2018-03-16 +categories: [functions] +keywords: [multilingual] +menu: + docs: + parent: "functions" +toc: false +signature: ["lang.Merge FROM TO"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +comments: +--- + +As an example: + +```bash +{{ $pages := .Site.RegularPages | lang.Merge $frSite.RegularPages | lang.Merge $enSite.RegularPages }} +``` + +Will "fill in the gaps" in the current site with, from left to right, content from the French site, and lastly the English. + + +A more practical example is to fill in the missing translations from the other languages: + +```bash +{{ $pages := .Site.RegularPages }} +{{ range .Site.Home.Translations }} +{{ $pages = $pages | lang.Merge .Site.RegularPages }} +{{ end }} + ``` diff --git a/docs/content/en/functions/lang.md b/docs/content/en/functions/lang.md new file mode 100644 index 000000000..1a4da807a --- /dev/null +++ b/docs/content/en/functions/lang.md @@ -0,0 +1,16 @@ +--- +title: lang +package: lang +description: "TODO.." +date: 2021-07-28 +categories: [functions] +keywords: [numbers] +menu: + docs: + parent: "functions" +signature: ["lang.NumFmt PRECISION NUMBER [OPTIONS [DELIMITER]]"] +aliases: ['/functions/numfmt/'] +type: 'template-func' + +--- + diff --git a/docs/content/en/functions/last.md b/docs/content/en/functions/last.md new file mode 100644 index 000000000..4a752cb82 --- /dev/null +++ b/docs/content/en/functions/last.md @@ -0,0 +1,27 @@ +--- +title: last +linktitle: last +description: "slices an array to only the last <em>N</em>th elements." +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: ["last INDEX COLLECTION"] +workson: [lists, taxonomies, terms, groups] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +``` +{{ range last 10 .Pages }} + {{ .Render "summary" }} +{{ end }} +``` diff --git a/docs/content/en/functions/le.md b/docs/content/en/functions/le.md new file mode 100644 index 000000000..1ff0ac582 --- /dev/null +++ b/docs/content/en/functions/le.md @@ -0,0 +1,24 @@ +--- +title: le +linktitle: le +description: Returns the boolean truth of arg1 <= arg2. +date: 2017-07-26 +publishdate: 2017-07-26 +lastmod: 2017-07-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [operators,logic] +signature: ["le ARG1 ARG2"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{ if le 5 10 }}true{{ end }} +``` diff --git a/docs/content/en/functions/len.md b/docs/content/en/functions/len.md new file mode 100644 index 000000000..0681583db --- /dev/null +++ b/docs/content/en/functions/len.md @@ -0,0 +1,63 @@ +--- +title: len +linktitle: len +description: Returns the length of a variable according to its type. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-04-18 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["len INPUT"] +workson: [lists,taxonomies,terms] +hugoversion: +relatedfuncs: [] +deprecated: false +toc: false +aliases: [] +--- + +`len` is a built-in function in Go that returns the length of a variable according to its type. From the Go documentation: + +> Array: the number of elements in v. +> +> Pointer to array: the number of elements in *v (even if v is nil). +> +> Slice, or map: the number of elements in v; if v is nil, len(v) is zero. +> +> String: the number of bytes in v. +> +> Channel: the number of elements queued (unread) in the channel buffer; if v is nil, len(v) is zero. + +`len` is also considered a [fundamental function for Hugo templating][]. + +## `len` Example 1: Longer Headings + +You may want to append a class to a heading according to the length of the string therein. The following templating checks to see if the title's length is greater than 80 characters and, if so, adds a `long-title` class to the `<h1>`: + +{{< code file="check-title-length.html" >}} +<header> + <h1{{if gt (len .Title) 80}} class="long-title"{{end}}>{{.Title}}</h1> +</header> +{{< /code >}} + +## `len` Example 2: Counting Pages with `where` + +The following templating uses [`where`][] in conjunction with `len` to +figure out the total number of content pages in a `posts` [section][]: + +{{< code file="how-many-posts.html" >}} +{{ $posts := (where .Site.RegularPages "Section" "==" "posts") }} +{{ $postCount := len $posts }} +{{< /code >}} + +Note the use of `.RegularPages`, a [site variable][] that counts all regular content pages but not the `_index.md` pages used to add front matter and content to [list templates][]. + + +[fundamental function for Hugo templating]: /templates/introduction/ +[list templates]: /templates/lists/ +[section]: /content-management/sections/ +[site variable]: /variables/site/ +[`where`]: /functions/where/ diff --git a/docs/content/en/functions/lower.md b/docs/content/en/functions/lower.md new file mode 100644 index 000000000..0e8ba6c6d --- /dev/null +++ b/docs/content/en/functions/lower.md @@ -0,0 +1,23 @@ +--- +title: lower +linktitle: lower +description: Converts all characters in the provided string to lowercase. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings,casing] +signature: ["lower INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +``` +{{lower "BatMan"}} → "batman" +``` diff --git a/docs/content/en/functions/lt.md b/docs/content/en/functions/lt.md new file mode 100644 index 000000000..d2a234986 --- /dev/null +++ b/docs/content/en/functions/lt.md @@ -0,0 +1,24 @@ +--- +title: lt +linktitle: lt +description: Returns the boolean truth of arg1 < arg2. +date: 2017-07-26 +publishdate: 2017-07-26 +lastmod: 2017-07-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [operators,logic] +signature: ["lt ARG1 ARG2"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{ if lt 5 10 }}true{{ end }} +``` diff --git a/docs/content/en/functions/markdownify.md b/docs/content/en/functions/markdownify.md new file mode 100644 index 000000000..171c3bf10 --- /dev/null +++ b/docs/content/en/functions/markdownify.md @@ -0,0 +1,29 @@ +--- +title: markdownify +linktitle: markdownify +description: Runs the provided string through the Markdown processor. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [markdown,content] +categories: [functions] +menu: + docs: + parent: "functions" +signature: ["markdownify INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{ .Title | markdownify }} +``` + +*Note*: if you need [Render Hooks][], which `markdownify` doesn't currently +support, use [.RenderString](/functions/renderstring/) instead. + +[Render Hooks]: /getting-started/configuration-markup/#markdown-render-hooks diff --git a/docs/content/en/functions/math.md b/docs/content/en/functions/math.md new file mode 100644 index 000000000..2d98c4deb --- /dev/null +++ b/docs/content/en/functions/math.md @@ -0,0 +1,42 @@ +--- +title: Math +description: Hugo provides mathematical operators in templates. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2020-02-23 +keywords: [math, operators] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: [] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +| Function | Description | Example | +|--------------|-----------------------------------------------------------------------------|----------------------------------| +| `add` | Adds two numbers. | `{{add 1 2}}` → `3` | +| | *If one of the numbers is a float, the result is a float.* | `{{add 1.1 2}}` → `3.1` | +| `sub` | Subtracts two numbers. | `{{sub 3 2}}` → `1` | +| | *If one of the numbers is a float, the result is a float.* | `{{sub 3 2.5}}` → `0.5` | +| `mul` | Multiplies two numbers. | `{{mul 2 3}}` → `6` | +| | *If one of the numbers is a float, the result is a float.* | `{{mul 2 3.1}}` → `6.2` | +| `div` | Divides two numbers. | `{{div 6 3}}` → `2` | +| | | `{{div 6 4}}` → `1` | +| | *If one of the numbers is a float, the result is a float.* | `{{div 6 4.0}}` → `1.5` | +| `mod` | Modulus of two integers. | `{{mod 15 3}}` → `0` | +| `modBool` | Boolean of modulus of two integers. Evaluates to `true` if result equals 0. | `{{modBool 15 3}}` → `true` | +| `math.Ceil` | Returns the least integer value greater than or equal to the given number. | `{{math.Ceil 2.1}}` → `3` | +| `math.Floor` | Returns the greatest integer value less than or equal to the given number. | `{{math.Floor 1.9}}` → `1` | +| `math.Log` | Returns the natural logarithm of the given number. | `{{math.Log 42}}` → `3.737` | +| `math.Max` | Returns the greater of two numbers. | `{{math.Max 1 2}}` → `2` | +| `math.Min` | Returns the smaller of two numbers. | `{{math.Min 1 2}}` → `1` | +| `math.Pow` | Returns the first number raised to the power of the second number. | `{{math.Pow 2 3}}` → `8` | +| `math.Round` | Returns the nearest integer, rounding half away from zero. | `{{math.Round 1.5}}` → `2` | +| `math.Sqrt` | Returns the square root of the given number. | `{{math.Sqrt 81}}` → `9` | diff --git a/docs/content/en/functions/md5.md b/docs/content/en/functions/md5.md new file mode 100644 index 000000000..7db856a75 --- /dev/null +++ b/docs/content/en/functions/md5.md @@ -0,0 +1,30 @@ +--- +title: md5 +linktitle: md5 +description: hashes the given input and returns its MD5 checksum. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["md5 INPUT"] +workson: [] +hugoversion: +relatedfuncs: [sha] +deprecated: false +aliases: [] +--- + +``` +{{ md5 "Hello world, gophers!" }} +<!-- returns the string "b3029f756f98f79e7f1b7f1d1f0dd53b" --> +``` + +This can be useful if you want to use [Gravatar](https://en.gravatar.com/) for generating a unique avatar: + +``` +<img src="https://www.gravatar.com/avatar/{{ md5 "your@email.com" }}?s=100&d=identicon"> +``` diff --git a/docs/content/en/functions/merge.md b/docs/content/en/functions/merge.md new file mode 100644 index 000000000..0944815a1 --- /dev/null +++ b/docs/content/en/functions/merge.md @@ -0,0 +1,71 @@ +--- +title: merge +description: "Returns the result of merging two or more maps." +date: 2019-08-08 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [dictionary] +signature: ["collections.Merge MAP MAP...", "merge MAP MAP..."] +workson: [] +hugoversion: "0.56.0" +relatedfuncs: [dict, append, reflect.IsMap, reflect.IsSlice] +aliases: [] +--- + +Returns the result of merging two or more maps from left to right. If a key already exists, `merge` updates its value. If a key is absent, `merge` inserts the value under the new key. + +Key handling is case-insensitive. + +The following examples use these map definitions: + +```go-html-template +{{ $m1 := dict "x" "foo" }} +{{ $m2 := dict "x" "bar" "y" "wibble" }} +{{ $m3 := dict "x" "baz" "y" "wobble" "z" (dict "a" "huey") }} +``` + +Example 1 + +```go-html-template +{{ $merged := merge $m1 $m2 $m3 }} + +{{ $merged.x }} --> baz +{{ $merged.y }} --> wobble +{{ $merged.z.a }} --> huey +``` + +Example 2 + +```go-html-template +{{ $merged := merge $m3 $m2 $m1 }} + +{{ $merged.x }} --> foo +{{ $merged.y }} --> wibble +{{ $merged.z.a }} --> huey +``` + +Example 3 + +```go-html-template +{{ $merged := merge $m2 $m3 $m1 }} + +{{ $merged.x }} --> foo +{{ $merged.y }} --> wobble +{{ $merged.z.a }} --> huey +``` + +Example 4 + +```go-html-template +{{ $merged := merge $m1 $m3 $m2 }} + +{{ $merged.x }} --> bar +{{ $merged.y }} --> wibble +{{ $merged.z.a }} --> huey +``` + +{{% note %}} +Regardless of depth, merging only applies to maps. For slices, use [append]({{< ref "functions/append" >}}). +{{% /note %}} diff --git a/docs/content/en/functions/ne.md b/docs/content/en/functions/ne.md new file mode 100644 index 000000000..e072993d2 --- /dev/null +++ b/docs/content/en/functions/ne.md @@ -0,0 +1,24 @@ +--- +title: ne +linktitle: ne +description: Returns the boolean truth of arg1 != arg2. +date: 2017-07-26 +publishdate: 2017-07-26 +lastmod: 2017-07-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [operators,logic] +signature: ["ne ARG1 ARG2"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{ if ne .Section "blog" }}current{{ end }} +``` diff --git a/docs/content/en/functions/now.md b/docs/content/en/functions/now.md new file mode 100644 index 000000000..24e1ab3f7 --- /dev/null +++ b/docs/content/en/functions/now.md @@ -0,0 +1,49 @@ +--- +title: now +linktitle: now +description: Returns the current local time +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-04-30 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [dates,time] +signature: ["now"] +workson: [] +hugoversion: +relatedfuncs: [Unix,dateFormat] +deprecated: false +aliases: [] +--- + +See [`time.Time`](https://godoc.org/time#Time). + +For example, building your site on June 24, 2017, with the following templating: + +``` +<div> + <small>© {{ now.Format "2006"}}</small> +</div> +``` + +would produce the following: + +``` +<div> + <small>© 2017</small> +</div> +``` + +The above example uses the [`.Format` function](/functions/format), which page includes a full listing of date formatting using Go's layout string. + +{{% note %}} +Older Hugo themes may still be using the obsolete Page’s `.Now` (uppercase with leading dot), which causes build error that looks like the following: + + ERROR ... Error while rendering "..." in "...": ... + executing "..." at <.Now.Format>: + can't evaluate field Now in type *hugolib.PageOutput + +Be sure to use `now` (lowercase with _**no**_ leading dot) in your templating. +{{% /note %}} diff --git a/docs/content/en/functions/os.Stat.md b/docs/content/en/functions/os.Stat.md new file mode 100644 index 000000000..a56f79735 --- /dev/null +++ b/docs/content/en/functions/os.Stat.md @@ -0,0 +1,32 @@ +--- +title: os.Stat +description: Returns a FileInfo structure describing a file or directory. +date: 2018-08-07 +publishdate: 2018-08-07 +lastmod: 2021-11-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [files] +signature: ["os.Stat PATH"] +workson: [] +hugoversion: +relatedfuncs: ['os.FileExists','os.ReadDir','os.ReadFile'] +deprecated: false +aliases: [] +--- +The `os.Stat` function attempts to resolve the path relative to the root of your project directory. If a matching file or directory is not found, it will attempt to resolve the path relative to the [`contentDir`]({{< relref "getting-started/configuration#contentdir">}}). A leading path separator (`/`) is optional. + +```go-html-template +{{ $f := os.Stat "README.md" }} +{{ $f.IsDir }} --> false (bool) +{{ $f.ModTime }} --> 2021-11-25 10:06:49.315429236 -0800 PST (time.Time) +{{ $f.Name }} --> README.md (string) +{{ $f.Size }} --> 241 (int64) + +{{ $d := os.Stat "content" }} +{{ $d.IsDir }} --> true (bool) +``` + +Details of the `FileInfo` structure are available in the [Go documentation](https://pkg.go.dev/io/fs#FileInfo). diff --git a/docs/content/en/functions/param.md b/docs/content/en/functions/param.md new file mode 100644 index 000000000..eb0a87279 --- /dev/null +++ b/docs/content/en/functions/param.md @@ -0,0 +1,40 @@ +--- +title: .Param +description: Calls page or site variables into your template. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-04-30 +keywords: ["front matter"] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: [".Param KEY"] +workson: [] +hugoversion: +relatedfuncs: [default] +deprecated: false +draft: false +aliases: [] +--- + +In Hugo, you can declare [site-wide params][sitevars] (i.e. in your [configuration][]), as well as params for [individual pages][pagevars]. + +A common use case is to have a general value for the site and a more specific value for some of the pages (e.g., an image). + +You can use the `.Param` method to call these values into your template. The following will first look for an `image` param in a specific content's [front matter][]. If not found, Hugo will look for an `image` param in your site's configuration: + +``` +$.Param "image" +``` + +{{% note %}} +The `Param` method may not consider empty strings in a content's front matter as "not found." If you are setting preconfigured front matter fields to empty strings using Hugo's archetypes, it may be best to use the [`default` function](/functions/default/) instead of `Param`. See the [related issue on GitHub](https://github.com/gohugoio/hugo/issues/3366). +{{% /note %}} + + +[configuration]: /getting-started/configuration/ +[front matter]: /content-management/front-matter/ +[pagevars]: /variables/page/ +[sitevars]: /variables/site/ diff --git a/docs/content/en/functions/partialCached.md b/docs/content/en/functions/partialCached.md new file mode 100644 index 000000000..d7a70ac64 --- /dev/null +++ b/docs/content/en/functions/partialCached.md @@ -0,0 +1,46 @@ +--- +title: partialCached +linktitle: partialCached +description: Allows for caching of partials that do not need to be re-rendered on every invocation. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [performance] +signature: ["partialCached LAYOUT INPUT [VARIANT...]"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +The `partialCached` template function can offer significant performance gains for complex templates that don't need to be re-rendered on every invocation. + +**Note:** Each Site (or language) has its own `partialCached` cache, so each site will execute a partial once. + +Here is the simplest usage: + +``` +{{ partialCached "footer.html" . }} +``` + +You can also pass additional parameters to `partialCached` to create *variants* of the cached partial. For example, if you have a complex partial that should be identical when rendered for pages within the same section, you could use a variant based upon section so that the partial is only rendered once per section: + +{{< code file="partial-cached-example.html" >}} +{{ partialCached "footer.html" . .Section }} +{{< /code >}} + +If you need to pass additional parameters to create unique variants, you can pass as many variant parameters as you need: + +``` +{{ partialCached "footer.html" . .Params.country .Params.province }} +``` + +Note that the variant parameters are not made available to the underlying partial template. They are only use to create a unique cache key. Since Hugo `0.61.0` you can use any object as cache key(s), not just strings. + + +> See also the [The Full Partial Series Part 1: Caching!](https://regisphilibert.com/blog/2019/12/hugo-partial-series-part-1-caching-with-partialcached/) diff --git a/docs/content/en/functions/path.Base.md b/docs/content/en/functions/path.Base.md new file mode 100644 index 000000000..c44518a72 --- /dev/null +++ b/docs/content/en/functions/path.Base.md @@ -0,0 +1,30 @@ +--- +title: path.Base +description: Base returns the last element of a path. +date: 2018-11-28 +publishdate: 2018-11-28 +lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [path, base] +signature: ["path.Base PATH"] +workson: [] +hugoversion: "0.40" +relatedfuncs: [path.Dir, path.Ext, path.Split] +deprecated: false +--- + +`path.Base` returns the last element of `PATH`. + +If `PATH` is empty, `.` is returned. + +**Note:** On Windows, `PATH` is converted to slash (`/`) separators. + +``` +{{ path.Base "a/news.html" }} → "news.html" +{{ path.Base "news.html" }} → "news.html" +{{ path.Base "a/b/c" }} → "c" +{{ path.Base "/x/y/z/" }} → "z" +``` diff --git a/docs/content/en/functions/path.Clean.md b/docs/content/en/functions/path.Clean.md new file mode 100644 index 000000000..03ffbd836 --- /dev/null +++ b/docs/content/en/functions/path.Clean.md @@ -0,0 +1,26 @@ +--- +title: path.Clean +description: Replaces path separators with slashes (`/`) and removes extraneous separators. +date: 2021-10-08 +# publishdate: 2018-11-28 +# lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [path] +signature: ["path.Clean PATH"] +--- + +`path.Clean` replaces path separators with slashes (`/`) and removes extraneous separators, including trailing separators. + +``` +{{ path.Clean "foo//bar" }} → "foo/bar" +{{ path.Clean "/foo/bar/" }} → "/foo/bar" +``` + +On a Windows system, if `.File.Path` is `foo\bar.md`, then: + +``` +{{ path.Clean .File.Path }} → "foo/bar.md" +``` diff --git a/docs/content/en/functions/path.Dir.md b/docs/content/en/functions/path.Dir.md new file mode 100644 index 000000000..851a3dc83 --- /dev/null +++ b/docs/content/en/functions/path.Dir.md @@ -0,0 +1,31 @@ +--- +title: path.Dir +description: Dir returns all but the last element of a path. +date: 2018-11-28 +publishdate: 2018-11-28 +lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [path, dir] +signature: ["path.Dir PATH"] +workson: [] +hugoversion: "0.40" +relatedfuncs: [path.Base, path.Ext, path.Split] +deprecated: false +--- + +`path.Dir` returns all but the last element of `PATH`, typically `PATH`'s directory. + +The returned path will never end in a slash. +If `PATH` is empty, `.` is returned. + +**Note:** On Windows, `PATH` is converted to slash (`/`) separators. + +``` +{{ path.Dir "a/news.html" }} → "a" +{{ path.Dir "news.html" }} → "." +{{ path.Dir "a/b/c" }} → "a/b" +{{ path.Dir "/x/y/z" }} → "/x/y" +``` diff --git a/docs/content/en/functions/path.Ext.md b/docs/content/en/functions/path.Ext.md new file mode 100644 index 000000000..73db7ab38 --- /dev/null +++ b/docs/content/en/functions/path.Ext.md @@ -0,0 +1,28 @@ +--- +title: path.Ext +description: Ext returns the file name extension of a path. +date: 2018-11-28 +publishdate: 2018-11-28 +lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [path, ext, extension] +signature: ["path.Ext PATH"] +workson: [] +hugoversion: "0.40" +relatedfuncs: [path.Base, path.Dir, path.Split] +deprecated: false +--- + +`path.Ext` returns the file name extension `PATH`. + +The extension is the suffix beginning at the final dot in the final slash-separated element `PATH`; +it is empty if there is no dot. + +**Note:** On Windows, `PATH` is converted to slash (`/`) separators. + +``` +{{ path.Ext "a/b/c/news.html" }} → ".html" +``` diff --git a/docs/content/en/functions/path.Join.md b/docs/content/en/functions/path.Join.md new file mode 100644 index 000000000..96ce86322 --- /dev/null +++ b/docs/content/en/functions/path.Join.md @@ -0,0 +1,28 @@ +--- +title: path.Join +description: Join path elements into a single path. +date: 2018-11-28 +publishdate: 2018-11-28 +lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [path, join] +signature: ["path.Join ELEMENT..."] +workson: [] +hugoversion: "0.39" +relatedfuncs: [path.Split] +deprecated: false +--- + +`path.Join` joins path elements into a single path, adding a separating slash if necessary. +All empty strings are ignored. + +**Note:** All path elements on Windows are converted to slash ('/') separators. + +``` +{{ path.Join "partial" "news.html" }} → "partial/news.html" +{{ path.Join "partial/" "news.html" }} → "partial/news.html" +{{ path.Join "foo/baz" "bar" }} → "foo/baz/bar" +``` diff --git a/docs/content/en/functions/path.Split.md b/docs/content/en/functions/path.Split.md new file mode 100644 index 000000000..9a09fbe4a --- /dev/null +++ b/docs/content/en/functions/path.Split.md @@ -0,0 +1,30 @@ +--- +title: path.Split +description: Split path immediately following the final slash. +date: 2018-11-28 +publishdate: 2018-11-28 +lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [path, split] +signature: ["path.Split PATH"] +workson: [] +hugoversion: "0.39" +relatedfuncs: [path.Split] +deprecated: false +--- + +`path.Split` splits `PATH` immediately following the final slash, separating it into a directory and a base component. + +The returned values have the property that `PATH` = `DIR`+`BASE`. +If there is no slash in `PATH`, it returns an empty directory and the base is set to `PATH`. + +**Note:** On Windows, `PATH` is converted to slash (`/`) separators. + +``` +{{ $dirFile := path.Split "a/news.html" }} → $dirFile.Dir → "a/", $dirFile.File → "news.html" +{{ $dirFile := path.Split "news.html" }} → $dirFile.Dir → "", $dirFile.File → "news.html" +{{ $dirFile := path.Split "a/b/c" }} → $dirFile.Dir → "a/b/", $dirFile.File → "c" +``` diff --git a/docs/content/en/functions/plainify.md b/docs/content/en/functions/plainify.md new file mode 100644 index 000000000..1258c139a --- /dev/null +++ b/docs/content/en/functions/plainify.md @@ -0,0 +1,27 @@ +--- +title: plainify +linktitle: plainify +description: Strips any HTML and returns the plain text version of the provided string. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-04-30 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["plainify INPUT"] +workson: [] +hugoversion: +relatedfuncs: [jsonify] +deprecated: false +aliases: [] +--- + +``` +{{ "<b>BatMan</b>" | plainify }} → "BatMan" +``` + +See also the `.PlainWords`, `.Plain`, and `.RawContent` [page variables][pagevars]. + +[pagevars]: /variables/page/ diff --git a/docs/content/en/functions/pluralize.md b/docs/content/en/functions/pluralize.md new file mode 100644 index 000000000..9c5040934 --- /dev/null +++ b/docs/content/en/functions/pluralize.md @@ -0,0 +1,23 @@ +--- +title: pluralize +linktitle: pluralize +description: Pluralizes the given word according to a set of common English pluralization rules +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["pluralize INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +``` +{{ "cat" | pluralize }} → "cats" +``` diff --git a/docs/content/en/functions/print.md b/docs/content/en/functions/print.md new file mode 100644 index 000000000..42b8dcb75 --- /dev/null +++ b/docs/content/en/functions/print.md @@ -0,0 +1,26 @@ +--- +title: print +linktitle: print +description: Prints the default representation of the given arguments using the standard `fmt.Print` function. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["print INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +See [the go doc](https://golang.org/pkg/fmt/) for additional information. + +``` +{{ print "foo" }} → "foo" +{{ print "foo" "bar" }} → "foobar" +{{ print (slice 1 2 3) }} → [1 2 3] +``` diff --git a/docs/content/en/functions/printf.md b/docs/content/en/functions/printf.md new file mode 100644 index 000000000..8b12b9883 --- /dev/null +++ b/docs/content/en/functions/printf.md @@ -0,0 +1,28 @@ +--- +title: printf +linktitle: printf +description: Formats a string using the standard `fmt.Sprintf` function. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["printf FORMAT INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +See [the go doc](https://golang.org/pkg/fmt/) for additional information. + +``` +{{ i18n ( printf "combined_%s" $var ) }} +``` + +``` +{{ printf "formatted %.2f" 3.1416 }} +``` diff --git a/docs/content/en/functions/println.md b/docs/content/en/functions/println.md new file mode 100644 index 000000000..1ea70cbad --- /dev/null +++ b/docs/content/en/functions/println.md @@ -0,0 +1,24 @@ +--- +title: println +linktitle: println +description: Prints the default representation of the given argument using the standard `fmt.Print` function and enforces a linebreak. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["println INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +See [the go doc](https://golang.org/pkg/fmt/) for additional information. `\n` denotes the linebreak but isn't printed in the templates as seen below: + +``` +{{ println "foo" }} → "foo\n" +``` diff --git a/docs/content/en/functions/querify.md b/docs/content/en/functions/querify.md new file mode 100644 index 000000000..9e8c4b83f --- /dev/null +++ b/docs/content/en/functions/querify.md @@ -0,0 +1,36 @@ +--- +title: querify +linktitle: querify +description: Takes a set or slice of key-value pairs and returns a query string to be appended to URLs. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [urls] +signature: ["querify KEY VALUE [KEY VALUE]...", "querify COLLECTION"] +hugoversion: +deprecated: false +workson: [] +relatedfuncs: [] +aliases: [] +--- + +`querify` takes a set or slice of key-value pairs and returns a [query string](https://en.wikipedia.org/wiki/Query_string) that can be appended to a URL. + +The following examples create a link to a search results page on Google. + +```go-html-template +<a href="https://www.google.com?{{ (querify "q" "test" "page" 3) | safeURL }}">Search</a> + +{{ $qs := slice "q" "test" "page" 3 }} +<a href="https://www.google.com?{{ (querify $qs) | safeURL }}">Search</a> +``` + +Both of these examples render the following HTML: + +```html +<a href="https://www.google.com?page=3&q=test">Search</a> +``` diff --git a/docs/content/en/functions/range.md b/docs/content/en/functions/range.md new file mode 100644 index 000000000..599e2ad25 --- /dev/null +++ b/docs/content/en/functions/range.md @@ -0,0 +1,24 @@ +--- +title: range +linktitle: +description: Iterates over a map, array, or slice. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [iteration] +signature: ["range COLLECTION"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +Just like in the Go programming language, Go and Hugo templates make heavy use of `range` to iterate over a map, array or slice. Other templating languages use a foreach for the equivalent functionality. + +`range` is fundamental to templating in Hugo. (See the [Introduction to Hugo Templates](/templates/introduction/) for more examples.) diff --git a/docs/content/en/functions/readdir.md b/docs/content/en/functions/readdir.md new file mode 100644 index 000000000..70fe7b66c --- /dev/null +++ b/docs/content/en/functions/readdir.md @@ -0,0 +1,51 @@ +--- +title: readDir +description: Returns an array of FileInfo structures sorted by filename, one element for each directory entry. +publishdate: 2017-02-01 +lastmod: 2021-11-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [files] +signature: ["os.ReadDir PATH", "readDir PATH"] +workson: [] +hugoversion: +relatedfuncs: ['os.FileExists','os.ReadFile','os.Stat'] +deprecated: false +aliases: [] +--- +The `os.ReadDir` function resolves the path relative to the root of your project directory. A leading path separator (`/`) is optional. + +With this directory structure: + +```text +content/ +├── about.md +├── contact.md +└── news/ + ├── article-1.md + └── article-2.md +``` + +This template code: + +```go-html-template +{{ range os.ReadDir "content" }} + {{ .Name }} --> {{ .IsDir }} +{{ end }} +``` + +Produces: + +```html +about.md --> false +contact.md --> false +news --> true +``` + +Note that `os.ReadDir` is not recursive. + +Details of the `FileInfo` structure are available in the [Go documentation](https://pkg.go.dev/io/fs#FileInfo). + +For more information on using `readDir` and `readFile` in your templates, see [Local File Templates]({{< relref "/templates/files" >}}). diff --git a/docs/content/en/functions/readfile.md b/docs/content/en/functions/readfile.md new file mode 100644 index 000000000..b0a88458b --- /dev/null +++ b/docs/content/en/functions/readfile.md @@ -0,0 +1,41 @@ +--- +title: readFile +description: Returns the contents of a file. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2021-11-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [files] +signature: ["os.ReadFile PATH", "readFile PATH"] +workson: [] +hugoversion: +relatedfuncs: ['os.FileExists','os.ReadDir','os.Stat'] +deprecated: false +aliases: [] +--- +The `os.ReadFile` function attempts to resolve the path relative to the root of your project directory. If a matching file is not found, it will attempt to resolve the path relative to the [`contentDir`]({{< relref "getting-started/configuration#contentdir">}}). A leading path separator (`/`) is optional. + +With a file named README.md in the root of your project directory: + +```text +This is **bold** text. +``` + +This template code: + +```go-html-template +{{ os.ReadFile "README.md" }} +``` + +Produces: + +```html +This is **bold** text. +``` + +Note that `os.ReadFile` returns raw (uninterpreted) content. + +For more information on using `readDir` and `readFile` in your templates, see [Local File Templates]({{< relref "/templates/files" >}}). diff --git a/docs/content/en/functions/ref.md b/docs/content/en/functions/ref.md new file mode 100644 index 000000000..ade380420 --- /dev/null +++ b/docs/content/en/functions/ref.md @@ -0,0 +1,50 @@ +--- +title: ref +linktitle: ref +description: Returns the absolute permalink to a page. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2020-09-05 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [cross references, anchors] +signature: ["ref . PAGE"] +workson: [] +hugoversion: +relatedfuncs: [relref] +deprecated: false +aliases: [] +--- + +This function takes two parameters: + +- The context of the page from which to resolve relative paths, typically the current page (`.`) +- The path to a page, with or without a file extension, with or without an anchor. A path without a leading `/` is first resolved relative to the given context, then to the remainder of the site. + +```go-html-template +{{ ref . "about" }} +{{ ref . "about#anchor" }} +{{ ref . "about.md" }} +{{ ref . "about.md#anchor" }} +{{ ref . "#anchor" }} +{{ ref . "/blog/my-post" }} +{{ ref . "/blog/my-post.md" }} +``` + +To return the absolute permalink to another language version of a page: + +```go-html-template +{{ ref . (dict "path" "about.md" "lang" "fr") }} +``` + +To return the absolute permalink to another Output Format of a page: + +```go-html-template +{{ ref . (dict "path" "about.md" "outputFormat" "rss") }} +``` + +Hugo emits an error or warning if the page cannot be uniquely resolved. The error behavior is configurable; see [Ref and RelRef Configuration](/content-management/cross-references/#ref-and-relref-configuration). + +This function is used by Hugo's built-in [`ref`](/content-management/shortcodes/#ref-and-relref) shortcode. For a detailed explanation of how to leverage this shortcode for content management, see [Links and Cross References](/content-management/cross-references/). diff --git a/docs/content/en/functions/reflect.IsMap.md b/docs/content/en/functions/reflect.IsMap.md new file mode 100644 index 000000000..9ad50b599 --- /dev/null +++ b/docs/content/en/functions/reflect.IsMap.md @@ -0,0 +1,24 @@ +--- +title: reflect.IsMap +description: Reports if a value is a map. +date: 2018-11-28 +publishdate: 2018-11-28 +lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [reflect, reflection, kind] +signature: ["reflect.IsMap INPUT"] +workson: [] +hugoversion: "v0.53" +relatedfuncs: [reflect.IsSlice] +deprecated: false +--- + +`reflect.IsMap` reports if `VALUE` is a map. Returns a boolean. + +``` +{{ reflect.IsMap (dict "key" "value") }} → true +{{ reflect.IsMap "yo" }} → false +``` diff --git a/docs/content/en/functions/reflect.IsSlice.md b/docs/content/en/functions/reflect.IsSlice.md new file mode 100644 index 000000000..38640918a --- /dev/null +++ b/docs/content/en/functions/reflect.IsSlice.md @@ -0,0 +1,24 @@ +--- +title: reflect.IsSlice +description: Reports if a value is a slice. +date: 2018-11-28 +publishdate: 2018-11-28 +lastmod: 2018-11-28 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [reflect, reflection, kind] +signature: ["reflect.IsSlice INPUT"] +workson: [] +hugoversion: "0.53" +relatedfuncs: [reflect.IsMap] +deprecated: false +--- + +`reflect.IsSlice` reports if `VALUE` is a slice. Returns a boolean. + +``` +{{ reflect.IsSlice (slice 1 2 3) }} → true +{{ reflect.IsSlice "yo" }} → false +``` diff --git a/docs/content/en/functions/relLangURL.md b/docs/content/en/functions/relLangURL.md new file mode 100644 index 000000000..e624aa355 --- /dev/null +++ b/docs/content/en/functions/relLangURL.md @@ -0,0 +1,29 @@ +--- +title: relLangURL +description: Adds the relative URL with correct language prefix according to site configuration for multilingual. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [multilingual,i18n,urls] +categories: [functions] +menu: + docs: + parent: "functions" +signature: ["relLangURL INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +`absLangURL` and `relLangURL` functions are similar to their [`absURL`](/functions/absurl/) and [`relURL`](/functions/relurl/) relatives but will add the correct language prefix when the site is configured with more than one language. (See [Configuring Multilingual][multiliconfig].) + +So for a site `baseURL` set to `https://example.com/hugo/` and the current language is `en`: + +``` +{{ "blog/" | absLangURL }} → "https://example.com/hugo/en/blog/" +{{ "blog/" | relLangURL }} → "/hugo/en/blog/" +``` + +[multiliconfig]: /content-management/multilingual/#configuring-multilingual-mode diff --git a/docs/content/en/functions/relref.md b/docs/content/en/functions/relref.md new file mode 100644 index 000000000..dbac2f3db --- /dev/null +++ b/docs/content/en/functions/relref.md @@ -0,0 +1,57 @@ +--- +title: relref +linktitle: relref +description: Returns the relative permalink to a page. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2020-09-05 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [cross references, anchors] +signature: ["relref . PAGE"] +workson: [] +hugoversion: +relatedfuncs: [ref] +deprecated: false +aliases: [] +--- + +This function takes two parameters: + +- The context of the page from which to resolve relative paths, typically the current page (`.`) +- The path to a page, with or without a file extension, with or without an anchor. A path without a leading `/` is first resolved relative to the given context, then to the remainder of the site. + +```go-html-template +{{ relref . "about" }} +{{ relref . "about#anchor" }} +{{ relref . "about.md" }} +{{ relref . "about.md#anchor" }} +{{ relref . "#anchor" }} +{{ relref . "/blog/my-post" }} +{{ relref . "/blog/my-post.md" }} +``` + +The permalink returned is relative to the protocol+host portion of the baseURL specified in the site configuration. For example: + +Code|baseURL|Permalink +:--|:--|:-- +`{{ relref . "/about" }}`|`http://example.org/`|`/about/` +`{{ relref . "/about" }}`|`http://example.org/x/`|`/x/about/` + +To return the relative permalink to another language version of a page: + +```go-html-template +{{ relref . (dict "path" "about.md" "lang" "fr") }} +``` + +To return the relative permalink to another Output Format of a page: + +```go-html-template +{{ relref . (dict "path" "about.md" "outputFormat" "rss") }} +``` + +Hugo emits an error or warning if the page cannot be uniquely resolved. The error behavior is configurable; see [Ref and RelRef Configuration](/content-management/cross-references/#ref-and-relref-configuration). + +This function is used by Hugo's built-in [`relref`](/content-management/shortcodes/#ref-and-relref) shortcode. For a detailed explanation of how to leverage this shortcode for content management, see [Links and Cross References](/content-management/cross-references/). diff --git a/docs/content/en/functions/relurl.md b/docs/content/en/functions/relurl.md new file mode 100644 index 000000000..af98c44f4 --- /dev/null +++ b/docs/content/en/functions/relurl.md @@ -0,0 +1,49 @@ +--- +title: relURL +description: Creates a baseURL-relative URL. +date: 2017-02-01 +publishdate: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [urls] +signature: ["relURL INPUT"] +workson: [] +hugoversion: +relatedfuncs: [absURL] +deprecated: false +aliases: [] +--- + +Both `absURL` and `relURL` consider the configured value of `baseURL` in your site's [`config` file][configuration]. Given a `baseURL` set to `https://example.com/hugo/`: + +``` +{{ "mystyle.css" | absURL }} → "https://example.com/hugo/mystyle.css" +{{ "mystyle.css" | relURL }} → "/hugo/mystyle.css" +{{ "http://gohugo.io/" | relURL }} → "http://gohugo.io/" +{{ "http://gohugo.io/" | absURL }} → "http://gohugo.io/" +``` + +The last two examples may look strange but can be very useful. For example, the following shows how to use `absURL` in [JSON-LD structured data for SEO][jsonld] where some of your images for a piece of content may or may not be hosted locally: + +{{< code file="layouts/partials/schemaorg-metadata.html" download="schemaorg-metadata.html" >}} +<script type="application/ld+json"> +{ + "@context" : "https://schema.org", + "@type" : "BlogPosting", + "image" : {{ apply .Params.images "absURL" "." }} +} +</script> +{{< /code >}} + +The above uses the [apply function][] and also exposes how the Go template parser JSON-encodes objects inside `<script>` tags. See [the safeJS template function][safejs] for examples of how to tell Hugo not to escape strings inside of such tags. + +{{% note "Ending Slash" %}} +`absURL` and `relURL` are smart about missing slashes, but they will *not* add a closing slash to a URL if it is not present. +{{% /note %}} + +[apply function]: /functions/apply/ +[configuration]: /getting-started/configuration/ +[jsonld]: https://developers.google.com/search/docs/advanced/structured-data/intro-structured-data +[safejs]: /functions/safejs diff --git a/docs/content/en/functions/render.md b/docs/content/en/functions/render.md new file mode 100644 index 000000000..c2347091f --- /dev/null +++ b/docs/content/en/functions/render.md @@ -0,0 +1,32 @@ +--- +title: .Render +description: Takes a view to apply when rendering content. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [views] +signature: [".Render LAYOUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +The view is an alternative layout and should be a file name that points to a template in one of the locations specified in the documentation for [Content Views](/templates/views). + +This function is only available when applied to a single piece of content within a [list context][]. + +This example could render a piece of content using the content view located at `/layouts/_default/summary.html`: + +``` +{{ range .Pages }} + {{ .Render "summary"}} +{{ end }} +``` + +[list context]: /templates/lists/ diff --git a/docs/content/en/functions/replace.md b/docs/content/en/functions/replace.md new file mode 100644 index 000000000..07b83d035 --- /dev/null +++ b/docs/content/en/functions/replace.md @@ -0,0 +1,28 @@ +--- +title: replace +description: Replaces all occurrences of the search string with the replacement string. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2020-09-07 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["strings.Replace INPUT OLD NEW [LIMIT]", "replace INPUT OLD NEW [LIMIT]"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +Replace returns a copy of `INPUT` with all occurrences of `OLD` replaced with `NEW`. +The number of replacements can be limited with an optional `LIMIT` parameter. + +``` +`{{ replace "Batman and Robin" "Robin" "Catwoman" }}` +→ "Batman and Catwoman" + +{{ replace "aabbaabb" "a" "z" 2 }} → "zzbbaabb" +``` diff --git a/docs/content/en/functions/replacere.md b/docs/content/en/functions/replacere.md new file mode 100644 index 000000000..a2149b6d3 --- /dev/null +++ b/docs/content/en/functions/replacere.md @@ -0,0 +1,34 @@ +--- +title: replaceRE +description: Replaces all occurrences of a regular expression with the replacement pattern. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2020-09-07 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [regex] +signature: ["strings.ReplaceRE PATTERN REPLACEMENT INPUT [LIMIT]", "replaceRE PATTERN REPLACEMENT INPUT [LIMIT]"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +`strings.ReplaceRE` returns a copy of `INPUT`, replacing all matches of the regular +expression `PATTERN` with the replacement text `REPLACEMENT`. +The number of replacements can be limited with an optional `LIMIT` parameter. + +``` +{{ replaceRE "^https?://([^/]+).*" "$1" "http://gohugo.io/docs" }}` → "gohugo.io" +{{ "http://gohugo.io/docs" | replaceRE "^https?://([^/]+).*" "$1" }}` → "gohugo.io" +{{ replaceRE "a+b" "X" "aabbaabbab" 1 }} → "Xbaabbab" +``` + +{{% note %}} +Hugo uses Go's [Regular Expression package](https://golang.org/pkg/regexp/), which is the same general syntax used by Perl, Python, and other languages but with a few minor differences for those coming from a background in PCRE. For a full syntax listing, see the [GitHub wiki for re2](https://github.com/google/re2/wiki/Syntax). + +If you are just learning RegEx, or at least Go's flavor, you can practice pattern matching in the browser at <https://regex101.com/>. +{{% /note %}} diff --git a/docs/content/en/functions/safeCSS.md b/docs/content/en/functions/safeCSS.md new file mode 100644 index 000000000..835ad3065 --- /dev/null +++ b/docs/content/en/functions/safeCSS.md @@ -0,0 +1,34 @@ +--- +title: safeCSS +description: Declares the provided string as a known "safe" CSS string. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-26 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [style,css,strings] +signature: ["safeCSS INPUT"] +workson: [] +hugoversion: +relatedfuncs: [safeHTML,safeHTMLAttr,] +deprecated: false +aliases: [] +--- + +In this context, *safe* means CSS content that matches any of the following: + +1. The CSS3 stylesheet production, such as `p { color: purple }`. +2. The CSS3 rule production, such as `a[href=~"https:"].foo#bar`. +3. CSS3 declaration productions, such as `color: red; margin: 2px`. +4. The CSS3 value production, such as `rgba(0, 0, 255, 127)`. + +Example: Given `style = "color: red;"` defined in the front matter of your `.md` file: + +* <span class="good">`<p style="{{ .Params.style | safeCSS }}">…</p>` → `<p style="color: red;">…</p>`</span> +* <span class="bad">`<p style="{{ .Params.style }}">…</p>` → `<p style="ZgotmplZ">…</p>`</span> + +{{% note "ZgotmplZ" %}} +"ZgotmplZ" is a special value that indicates that unsafe content reached a CSS or URL context. +{{% /note %}} diff --git a/docs/content/en/functions/safeHTML.md b/docs/content/en/functions/safeHTML.md new file mode 100644 index 000000000..3d5197a4f --- /dev/null +++ b/docs/content/en/functions/safeHTML.md @@ -0,0 +1,40 @@ +--- +title: safeHTML +# linktitle: +description: Declares a provided string as a "safe" HTML document to avoid escaping by Go templates. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["safeHTML INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +It should not be used for HTML from a third-party, or HTML with unclosed tags or comments. + +Given a site-wide [`config.toml`][config] with the following `copyright` value: + +{{< code-toggle file="config" >}} +copyright = "© 2015 Jane Doe. <a href=\"https://creativecommons.org/licenses/by/4.0/\">Some rights reserved</a>." +{{< /code-toggle >}} + +`{{ .Site.Copyright | safeHTML }}` in a template would then output: + +``` +© 2015 Jane Doe. <a href="https://creativecommons.org/licenses/by/4.0/">Some rights reserved</a>. +``` + +However, without the `safeHTML` function, html/template assumes `.Site.Copyright` to be unsafe and therefore escapes all HTML tags and renders the whole string as plain text: + +``` +<p>© 2015 Jane Doe. <a href="https://creativecommons.org/licenses by/4.0/">Some rights reserved</a>.</p> +``` + +[config]: /getting-started/configuration/ diff --git a/docs/content/en/functions/safeHTMLAttr.md b/docs/content/en/functions/safeHTMLAttr.md new file mode 100644 index 000000000..19de2e985 --- /dev/null +++ b/docs/content/en/functions/safeHTMLAttr.md @@ -0,0 +1,30 @@ +--- +title: safeHTMLAttr +# linktitle: safeHTMLAttr +description: Declares the provided string as a safe HTML attribute. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["safeHTMLAttr INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +Example: Given a site-wide `config.toml` that contains this menu entry: + +{{< code-toggle file="config" >}} +[[menu.main]] + name = "IRC: #golang at freenode" + url = "irc://irc.freenode.net/#golang" +{{< /code-toggle >}} + +* <span class="bad">`<a href="{{ .URL }}">` → `<a href="#ZgotmplZ">`</span> +* <span class="good">`<a {{ printf "href=%q" .URL | safeHTMLAttr }}>` → `<a href="irc://irc.freenode.net/#golang">`</span> diff --git a/docs/content/en/functions/safeJS.md b/docs/content/en/functions/safeJS.md new file mode 100644 index 000000000..c67bfa61c --- /dev/null +++ b/docs/content/en/functions/safeJS.md @@ -0,0 +1,29 @@ +--- +title: safeJS +# linktitle: +description: Declares the provided string as a known safe JavaScript string. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["safeJS INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +In this context, *safe* means the string encapsulates a known safe EcmaScript5 Expression (e.g., `(x + y * z())`). + +Template authors are responsible for ensuring that typed expressions do not break the intended precedence and that there is no statement/expression ambiguity as when passing an expression like `{ foo:bar() }\n['foo']()`, which is both a valid expression and a valid program with a very different meaning. + +Example: Given `hash = "619c16f"` defined in the front matter of your `.md` file: + +* <span class="good">`<script>var form_{{ .Params.hash | safeJS }};…</script>` → `<script>var form_619c16f;…</script>`</span> +* <span class="bad">`<script>var form_{{ .Params.hash }};…</script>` → `<script>var form_"619c16f";…</script>`</span> diff --git a/docs/content/en/functions/safeURL.md b/docs/content/en/functions/safeURL.md new file mode 100644 index 000000000..959076246 --- /dev/null +++ b/docs/content/en/functions/safeURL.md @@ -0,0 +1,71 @@ +--- +title: safeURL +description: Declares the provided string as a safe URL or URL substring. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [strings,urls] +categories: [functions] +menu: + docs: + parent: "functions" +signature: ["safeURL INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +`safeURL` declares the provided string as a "safe" URL or URL substring (see [RFC 3986][]). A URL like `javascript:checkThatFormNotEditedBeforeLeavingPage()` from a trusted source should go in the page, but by default dynamic `javascript:` URLs are filtered out since they are a frequently exploited injection vector. + +Without `safeURL`, only the URI schemes `http:`, `https:` and `mailto:` are considered safe by Go templates. If any other URI schemes (e.g., `irc:` and `javascript:`) are detected, the whole URL will be replaced with `#ZgotmplZ`. This is to "defang" any potential attack in the URL by rendering it useless. + +The following examples use a [site `config.toml`][configuration] with the following [menu entry][menus]: + +{{< code file="config.toml" copy="false" >}} +[[menu.main]] + name = "IRC: #golang at freenode" + url = "irc://irc.freenode.net/#golang" +{{< /code >}} + +The following is an example of a sidebar partial that may be used in conjunction with the preceding front matter example: + +{{< code file="layouts/partials/bad-url-sidebar-menu.html" copy="false" >}} +<!-- This unordered list may be part of a sidebar menu --> +<ul> + {{ range .Site.Menus.main }} + <li><a href="{{ .URL }}">{{ .Name }}</a></li> + {{ end }} +</ul> +{{< /code >}} + +This partial would produce the following HTML output: + +{{< output file="bad-url-sidebar-menu-output.html" >}} +<!-- This unordered list may be part of a sidebar menu --> +<ul> + <li><a href="#ZgotmplZ">IRC: #golang at freenode</a></li> +</ul> +{{< /output >}} + +The odd output can be remedied by adding ` | safeURL` to our `.URL` page variable: + +{{< code file="layouts/partials/correct-url-sidebar-menu.html" copy="false" >}} +<!-- This unordered list may be part of a sidebar menu --> +<ul> + <li><a href="{{ .URL | safeURL }}">{{ .Name }}</a></li> +</ul> +{{< /code >}} + +With the `.URL` page variable piped through `safeURL`, we get the desired output: + +{{< output file="correct-url-sidebar-menu-output.html" >}} +<ul class="sidebar-menu"> + <li><a href="irc://irc.freenode.net/#golang">IRC: #golang at freenode</a></li> +</ul> +{{< /output >}} + +[configuration]: /getting-started/configuration/ +[menus]: /content-management/menus/ +[RFC 3986]: https://tools.ietf.org/html/rfc3986 diff --git a/docs/content/en/functions/scratch.md b/docs/content/en/functions/scratch.md new file mode 100644 index 000000000..c64aa1119 --- /dev/null +++ b/docs/content/en/functions/scratch.md @@ -0,0 +1,154 @@ +--- +title: .Scratch +description: Acts as a "scratchpad" to store and manipulate data. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [iteration] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: [] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [/extras/scratch/,/doc/scratch/] +--- + +Scratch is a Hugo feature designed to conveniently manipulate data in a Go Template world. It is either a Page or Shortcode method for which the resulting data will be attached to the given context, or it can live as a unique instance stored in a variable. + +{{% note %}} +Note that Scratch was initially created as a workaround for a [Go template scoping limitation](https://github.com/golang/go/issues/10608) that affected Hugo versions prior to 0.48. For a detailed analysis of `.Scratch` and contextual use cases, see [this blog post](https://regisphilibert.com/blog/2017/04/hugo-scratch-explained-variable/). +{{% /note %}} + +### Contexted `.Scratch` vs. local `newScratch` + +Since Hugo 0.43, there are two different ways of using Scratch: + +#### The Page's `.Scratch` + +`.Scratch` is available as a Page method or a Shortcode method and attaches the "scratched" data to the given page. Either a Page or a Shortcode context is required to use `.Scratch`. + +```go-html-template +{{ .Scratch.Set "greeting" "bonjour" }} +{{ range .Pages }} + {{ .Scratch.Set "greeting" (print "bonjour" .Title) }} +{{ end }} +``` + +#### The local `newScratch` + +{{< new-in "0.43" >}} A Scratch instance can also be assigned to any variable using the `newScratch` function. In this case, no Page or Shortcode context is required and the scope of the scratch is only local. The methods detailed below are available from the variable the Scratch instance was assigned to. + +```go-html-template +{{ $data := newScratch }} +{{ $data.Set "greeting" "hola" }} +``` + +### Methods + +A Scratch has the following methods: + +{{% note %}} +Note that the following examples assume a [local Scratch instance](#the-local-newscratch) has been stored in `$scratch`. +{{% /note %}} + +#### .Set + +Set the value of a given key. + +```go-html-template +{{ $scratch.Set "greeting" "Hello" }} +``` + +#### .Get + +Get the value of a given key. + +```go-html-template +{{ $scratch.Set "greeting" "Hello" }} +---- +{{ $scratch.Get "greeting" }} > Hello +``` + +#### .Add + +Add a given value to existing value(s) of the given key. + +For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list. + +```go-html-template +{{ $scratch.Add "greetings" "Hello" }} +{{ $scratch.Add "greetings" "Welcome" }} +---- +{{ $scratch.Get "greetings" }} > HelloWelcome +``` + +```go-html-template +{{ $scratch.Add "total" 3 }} +{{ $scratch.Add "total" 7 }} +---- +{{ $scratch.Get "total" }} > 10 +``` + +```go-html-template +{{ $scratch.Add "greetings" (slice "Hello") }} +{{ $scratch.Add "greetings" (slice "Welcome" "Cheers") }} +---- +{{ $scratch.Get "greetings" }} > []interface {}{"Hello", "Welcome", "Cheers"} +``` + +#### .SetInMap + +Takes a `key`, `mapKey` and `value` and adds a map of `mapKey` and `value` to the given `key`. + +```go-html-template +{{ $scratch.SetInMap "greetings" "english" "Hello" }} +{{ $scratch.SetInMap "greetings" "french" "Bonjour" }} +---- +{{ $scratch.Get "greetings" }} > map[french:Bonjour english:Hello] +``` + +#### .DeleteInMap +Takes a `key` and `mapKey` and removes the map of `mapKey` from the given `key`. + +```go-html-template +{{ .Scratch.SetInMap "greetings" "english" "Hello" }} +{{ .Scratch.SetInMap "greetings" "french" "Bonjour" }} +---- +{{ .Scratch.DeleteInMap "greetings" "english" }} +---- +{{ .Scratch.Get "greetings" }} > map[french:Bonjour] +``` + +#### .GetSortedMapValues + +Return an array of values from `key` sorted by `mapKey`. + +```go-html-template +{{ $scratch.SetInMap "greetings" "english" "Hello" }} +{{ $scratch.SetInMap "greetings" "french" "Bonjour" }} +---- +{{ $scratch.GetSortedMapValues "greetings" }} > [Hello Bonjour] +``` + +#### .Delete + +{{< new-in "0.38" >}} Remove the given key. + +```go-html-template +{{ $scratch.Set "greeting" "Hello" }} +---- +{{ $scratch.Delete "greeting" }} +``` + +#### .Values + +Return the raw backing map. Note that you should only use this method on the locally scoped Scratch instances you obtain via [`newScratch`](#the-local-newscratch), not `.Page.Scratch` etc., as that will lead to concurrency issues. + + +[pagevars]: /variables/page/ diff --git a/docs/content/en/functions/seq.md b/docs/content/en/functions/seq.md new file mode 100644 index 000000000..c0750b4a1 --- /dev/null +++ b/docs/content/en/functions/seq.md @@ -0,0 +1,50 @@ +--- +title: seq +# linktitle: +description: Creates a sequence of integers. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["seq LAST", "seq FIRST LAST", "seq FIRST INCREMENT LAST"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +It's named and used in the model of [GNU's seq][]. + +``` +3 → 1, 2, 3 +1 2 4 → 1, 3 +-3 → -1, -2, -3 +1 4 → 1, 2, 3, 4 +1 -2 → 1, 0, -1, -2 +``` + +## Example: `seq` with `range` and `after` + +You can use `seq` in combination with `range` and `after`. The following will return 19 elements: + +``` +{{ range after 1 (seq 20)}} +{{ end }} +``` + +However, when ranging with an index, the following may be less confusing in that `$indexStartingAt1` and `$num` will return `1,2,3 ... 20`: + +``` +{{ range $index, $num := (seq 20) }} +$indexStartingAt1 := (add $index 1) +{{ end }} +``` + + +[GNU's seq]: https://www.gnu.org/software/coreutils/manual/html_node/seq-invocation.html#seq-invocation diff --git a/docs/content/en/functions/sha.md b/docs/content/en/functions/sha.md new file mode 100644 index 000000000..24ad165a8 --- /dev/null +++ b/docs/content/en/functions/sha.md @@ -0,0 +1,33 @@ +--- +title: sha +# linktitle: sha +description: Hashes the given input and returns either an SHA1 or SHA256 checksum. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [sha,checksum] +signature: ["sha1 INPUT", "sha256 INPUT"] +workson: [] +hugoversion: +relatedfuncs: [md5] +deprecated: false +aliases: [sha1, sha256] +--- + +`sha1` hashes the given input and returns its SHA1 checksum. + +``` +{{ sha1 "Hello world, gophers!" }} +<!-- returns the string "c8b5b0e33d408246e30f53e32b8f7627a7a649d4" --> +``` + +`sha256` hashes the given input and returns its SHA256 checksum. + +``` +{{ sha256 "Hello world, gophers!" }} +<!-- returns the string "6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46" --> +``` diff --git a/docs/content/en/functions/shuffle.md b/docs/content/en/functions/shuffle.md new file mode 100644 index 000000000..95a586e44 --- /dev/null +++ b/docs/content/en/functions/shuffle.md @@ -0,0 +1,38 @@ +--- +title: shuffle +# linktitle: +description: Returns a random permutation of a given array or slice. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-04-30 +keywords: [ordering] +categories: [functions] +menu: + docs: + parent: "functions" +signature: ["shuffle COLLECTION"] +workson: [] +hugoversion: +relatedfuncs: [seq] +deprecated: false +draft: false +aliases: [] +--- + +{{< code file="shuffle-input.html" >}} +<!-- Shuffled sequence = --> +<div>{{ shuffle (seq 1 5) }}</div> +<!-- Shuffled slice = --> +<div>{{ shuffle (slice "foo" "bar" "buzz") }}</div> +{{< /code >}} + +This example would return the following: + +{{< output file="shuffle-output.html" >}} +<!-- Shuffled sequence = --> +<div>2 5 3 1 4</div> +<!-- Shuffled slice = --> +<div>buzz foo bar</div> +{{< /output >}} + +This example also makes use of the [slice](/functions/slice/) and [seq](/functions/seq/) functions. diff --git a/docs/content/en/functions/singularize.md b/docs/content/en/functions/singularize.md new file mode 100644 index 000000000..8ca46d433 --- /dev/null +++ b/docs/content/en/functions/singularize.md @@ -0,0 +1,23 @@ +--- +title: singularize +# linktitle: singularize +description: Converts a word according to a set of common English singularization rules. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings,singular] +signature: ["singularize INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +`{{ "cats" | singularize }}` → "cat" + +See also the `.Data.Singular` [taxonomy variable](/variables/taxonomy/) for singularizing taxonomy names. diff --git a/docs/content/en/functions/site.md b/docs/content/en/functions/site.md new file mode 100644 index 000000000..d4b8e417c --- /dev/null +++ b/docs/content/en/functions/site.md @@ -0,0 +1,23 @@ +--- +title: site +linktitle: site +description: The `site` function provides global access to the same data as the `.Site` page method. +date: 2021-02-11 +publishdate: 2021-02-11 +lastmod: 2021-02-11 +keywords: [] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: ["site"] +workson: [] +hugoversion: +relatedfuncs: ["hugo"] +deprecated: false +draft: false +aliases: [] +--- + +`site` is a global function which returns the same data as the `.Site` page method. See: [Site Variables]({{< relref "/variables/site" >}}). diff --git a/docs/content/en/functions/slice.md b/docs/content/en/functions/slice.md new file mode 100644 index 000000000..0710d5e40 --- /dev/null +++ b/docs/content/en/functions/slice.md @@ -0,0 +1,31 @@ +--- +title: slice +# linktitle: slice +description: Creates a slice (array) of all passed arguments. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [slice, array, interface] +signature: ["slice ITEM..."] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +toc: false +--- + +One use case is the concatenation of elements in combination with the [`delimit` function][]: + +{{< code file="slice.html" >}} +{{ delimit (slice "foo" "bar" "buzz") ", " }} +<!-- returns the string "foo, bar, buzz" --> +{{< /code >}} + + +[`delimit` function]: /functions/delimit/ diff --git a/docs/content/en/functions/slicestr.md b/docs/content/en/functions/slicestr.md new file mode 100644 index 000000000..254ad9a61 --- /dev/null +++ b/docs/content/en/functions/slicestr.md @@ -0,0 +1,25 @@ +--- +title: slicestr +# linktitle: +description: Creates a slice of a half-open range, including start and end indices. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["slicestr STRING START [END]"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +For example, 1 and 4 creates a slice including elements 1 through 3. +The `end` index can be omitted; it defaults to the string's length. + +* `{{slicestr "BatMan" 3}}` → "Man" +* `{{slicestr "BatMan" 0 3}}` → "Bat" diff --git a/docs/content/en/functions/sort.md b/docs/content/en/functions/sort.md new file mode 100644 index 000000000..b48aad1aa --- /dev/null +++ b/docs/content/en/functions/sort.md @@ -0,0 +1,63 @@ +--- +title: sort +# linktitle: sort +description: Sorts maps, arrays, and slices and returns a sorted slice. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [ordering,sorting,lists] +signature: [] +workson: [lists,taxonomies,terms,groups] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +A sorted array of map values will be returned with the keys eliminated. There are two optional arguments: `sortByField` and `sortAsc`. If left blank, sort will sort by keys (for maps) in ascending order as its default behavior. + +``` +--- +tags: ["tag3", "tag1", "tag2"] +--- + +// Site config ++++ +[params.authors] + [params.authors.Joe] + firstName = "Joe" + lastName = "Bergevin" + [params.authors.Derek] + firstName = "Derek" + lastName = "Perkins" + [params.authors.Tanner] + firstName = "Tanner" + lastName = "Linsley" ++++ +``` + +``` +// Sort by value, ascending (default for lists) +Tags: {{ range sort .Params.tags }}{{ . }} {{ end }} + +→ Outputs Tags: tag1 tag2 tag3 + +// Sort by value, descending +Tags: {{ range sort .Params.tags "value" "desc" }}{{ . }} {{ end }} + +→ Outputs Tags: tag3 tag2 tag1 + +// Sort by key, ascending (default for maps) +Authors: {{ range sort .Site.Params.authors }}{{ .firstName }} {{ end }} + +→ Outputs Authors: Derek Joe Tanner + +// Sort by field, descending +Authors: {{ range sort .Site.Params.authors "lastName" "desc" }}{{ .lastName }} {{ end }} + +→ Outputs Authors: Perkins Linsley Bergevin +``` diff --git a/docs/content/en/functions/split.md b/docs/content/en/functions/split.md new file mode 100644 index 000000000..a66a7cf0c --- /dev/null +++ b/docs/content/en/functions/split.md @@ -0,0 +1,21 @@ +--- +title: split +# linktitle: split +description: splits a string into substrings separated by a delimiter +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["split STRING DELIM"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +* `{{split "tag1,tag2,tag3" "," }}` → ["tag1" "tag2" "tag3"] diff --git a/docs/content/en/functions/string.md b/docs/content/en/functions/string.md new file mode 100644 index 000000000..33a781e45 --- /dev/null +++ b/docs/content/en/functions/string.md @@ -0,0 +1,21 @@ +--- +title: string +# linktitle: string +description: Creates a string from the argument passed to the function +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["string INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +* `{{string "BatMan"}}` → "BatMan" diff --git a/docs/content/en/functions/strings.Count.md b/docs/content/en/functions/strings.Count.md new file mode 100644 index 000000000..f666a7843 --- /dev/null +++ b/docs/content/en/functions/strings.Count.md @@ -0,0 +1,29 @@ +--- +title: strings.Count +description: Returns the number of non-overlapping instances of a substring within a string. +date: 2020-09-07 +publishdate: 2020-09-07 +lastmod: 2020-09-07 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [count, counting, character count] +signature: ["strings.Count SUBSTR STRING"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + +{{< new-in "0.74.0" >}} + +If `SUBSTR` is an empty string, this function returns 1 plus the number of Unicode code points in `STRING`. + +Example|Result +:--|:-- +`{{ "aaabaab" \| strings.Count "a" }}`|5 +`{{ "aaabaab" \| strings.Count "aa" }}`|2 +`{{ "aaabaab" \| strings.Count "aaa" }}`|1 +`{{ "aaabaab" \| strings.Count "" }}`|8 diff --git a/docs/content/en/functions/strings.HasSuffix.md b/docs/content/en/functions/strings.HasSuffix.md new file mode 100644 index 000000000..3b82ea055 --- /dev/null +++ b/docs/content/en/functions/strings.HasSuffix.md @@ -0,0 +1,22 @@ +--- +title: strings.HasSuffix +description: Determine whether or not a given string ends with the provided trailing suffix string. +date: 2019-08-13 +publishdate: 2019-08-13 +lastmod: 2019-08-13 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["strings.HasSuffix STRING SUFFIX"] +workson: [] +hugoversion: +relatedfuncs: [hasPrefix] +deprecated: false +aliases: [] +--- + + {{ $pdfPath := "/path/to/some.pdf" }} + {{ strings.HasSuffix $pdfPath "pdf" }} → true + {{ strings.HasSuffix $pdfPath "txt" }} → false diff --git a/docs/content/en/functions/strings.Repeat.md b/docs/content/en/functions/strings.Repeat.md new file mode 100644 index 000000000..7cba6d075 --- /dev/null +++ b/docs/content/en/functions/strings.Repeat.md @@ -0,0 +1,23 @@ +--- +title: strings.Repeat +# linktitle: +description: Returns INPUT repeated COUNT times. +date: 2018-05-31 +publishdate: 2018-05-31 +lastmod: 2018-05-31 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["strings.Repeat COUNT INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +``` +{{ strings.Repeat 3 "yo" }} → "yoyoyo" +{{ "yo" | strings.Repeat 3 }} → "yoyoyo" +``` diff --git a/docs/content/en/functions/strings.RuneCount.md b/docs/content/en/functions/strings.RuneCount.md new file mode 100644 index 000000000..de335f862 --- /dev/null +++ b/docs/content/en/functions/strings.RuneCount.md @@ -0,0 +1,27 @@ +--- +title: strings.RuneCount +description: Determines the number of runes in a string. +date: 2018-06-01 +publishdate: 2018-06-01 +lastmod: 2018-06-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [counting, character count, length, rune length, rune count] +signature: ["strings.RuneCount INPUT"] +workson: [] +hugoversion: +relatedfuncs: ["len", "countrunes"] +deprecated: false +aliases: [] +--- + +In contrast with `strings.CountRunes` function, which strips HTML and whitespace before counting runes, `strings.RuneCount` simply counts all the runes in a string. It relies on the Go [`utf8.RuneCountInString`] function. + +``` +{{ "Hello, 世界" | strings.RuneCount }} +<!-- outputs a content length of 9 runes. --> +``` + +[`utf8.RuneCount`]: https://golang.org/pkg/unicode/utf8/#RuneCount diff --git a/docs/content/en/functions/strings.TrimLeft.md b/docs/content/en/functions/strings.TrimLeft.md new file mode 100644 index 000000000..2d71a1367 --- /dev/null +++ b/docs/content/en/functions/strings.TrimLeft.md @@ -0,0 +1,26 @@ +--- +title: strings.TrimLeft +description: Returns a slice of a given string with all leading characters contained in the cutset removed. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["strings.TrimLeft CUTSET STRING"] +workson: [] +hugoversion: +relatedfuncs: [strings.TrimRight] +deprecated: false +aliases: [] +--- + +Given the string `"abba"`, leading `"a"`'s can be removed a follows: + + {{ strings.TrimLeft "a" "abba" }} → "bba" + +Numbers can be handled as well: + + {{ strings.TrimLeft 12 1221341221 }} → "341221" diff --git a/docs/content/en/functions/strings.TrimPrefix.md b/docs/content/en/functions/strings.TrimPrefix.md new file mode 100644 index 000000000..a66bbe3db --- /dev/null +++ b/docs/content/en/functions/strings.TrimPrefix.md @@ -0,0 +1,24 @@ +--- +title: strings.TrimPrefix +description: Returns a given string s without the provided leading prefix string. If s doesn't start with prefix, s is returned unchanged. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["strings.TrimPrefix PREFIX STRING"] +workson: [] +hugoversion: +relatedfuncs: [strings.TrimSuffix] +deprecated: false +aliases: [] +--- + +Given the string `"aabbaa"`, the specified prefix is only removed if `"aabbaa"` starts with it: + + {{ strings.TrimPrefix "a" "aabbaa" }} → "abbaa" + {{ strings.TrimPrefix "aa" "aabbaa" }} → "bbaa" + {{ strings.TrimPrefix "aaa" "aabbaa" }} → "aabbaa" diff --git a/docs/content/en/functions/strings.TrimRight.md b/docs/content/en/functions/strings.TrimRight.md new file mode 100644 index 000000000..05084a4c0 --- /dev/null +++ b/docs/content/en/functions/strings.TrimRight.md @@ -0,0 +1,26 @@ +--- +title: strings.TrimRight +description: Returns a slice of a given string with all trailing characters contained in the cutset removed. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["strings.TrimRight CUTSET STRING"] +workson: [] +hugoversion: +relatedfuncs: [strings.TrimRight] +deprecated: false +aliases: [] +--- + +Given the string `"abba"`, trailing `"a"`'s can be removed a follows: + + {{ strings.TrimRight "a" "abba" }} → "abb" + +Numbers can be handled as well: + + {{ strings.TrimRight 12 1221341221 }} → "122134" diff --git a/docs/content/en/functions/strings.TrimSuffix.md b/docs/content/en/functions/strings.TrimSuffix.md new file mode 100644 index 000000000..916038054 --- /dev/null +++ b/docs/content/en/functions/strings.TrimSuffix.md @@ -0,0 +1,24 @@ +--- +title: strings.TrimSuffix +description: Returns a given string s without the provided trailing suffix string. If s doesn't end with suffix, s is returned unchanged. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["strings.TrimSuffix SUFFIX STRING"] +workson: [] +hugoversion: +relatedfuncs: [strings.TrimPrefix] +deprecated: false +aliases: [] +--- + +Given the string `"aabbaa"`, the specified suffix is only removed if `"aabbaa"` ends with it: + + {{ strings.TrimSuffix "a" "aabbaa" }} → "aabba" + {{ strings.TrimSuffix "aa" "aabbaa" }} → "aabb" + {{ strings.TrimSuffix "aaa" "aabbaa" }} → "aabbaa" diff --git a/docs/content/en/functions/substr.md b/docs/content/en/functions/substr.md new file mode 100644 index 000000000..31f733e0b --- /dev/null +++ b/docs/content/en/functions/substr.md @@ -0,0 +1,45 @@ +--- +title: substr +# linktitle: +description: Extracts parts of a string from a specified character's position and returns the specified number of characters. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +aliases: [] +signature: ["substr STRING START [LENGTH]"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +It normally takes two parameters: `start` and `length`. It can also take one parameter: `start`, i.e. `length` is omitted, in which case the substring starting from start until the end of the string will be returned. + +To extract characters from the end of the string, use a negative start number. + +If `length` is given and is negative, that number of characters will be omitted from the end of string. + +``` +{{ substr "abcdef" 0 }} → "abcdef" +{{ substr "abcdef" 1 }} → "bcdef" + +{{ substr "abcdef" 0 1 }} → "a" +{{ substr "abcdef" 1 1 }} → "b" + +{{ substr "abcdef" 0 -1 }} → "abcde" +{{ substr "abcdef" 1 -1 }} → "bcde" + +{{ substr "abcdef" -1 }} → "f" +{{ substr "abcdef" -2 }} → "ef" + +{{ substr "abcdef" -1 1 }} → "f" +{{ substr "abcdef" -2 1 }} → "e" + +{{ substr "abcdef" -3 -1 }} → "de" +{{ substr "abcdef" -3 -2 }} → "d" +``` diff --git a/docs/content/en/functions/symdiff.md b/docs/content/en/functions/symdiff.md new file mode 100644 index 000000000..da269a422 --- /dev/null +++ b/docs/content/en/functions/symdiff.md @@ -0,0 +1,28 @@ +--- +title: "symdiff" +description: "`collections.SymDiff` (alias `symdiff`) returns the symmetric difference of two collections." +date: 2018-11-07 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [collections,intersect,union,complement] +signature: ["COLLECTION | symdiff COLLECTION" ] +hugoversion: "0.51" +aliases: [] +--- + +Example: + +```go-html-template +{{ slice 1 2 3 | symdiff (slice 3 4) }} +``` + +The above will print `[1 2 4]`. + +Also see https://en.wikipedia.org/wiki/Symmetric_difference + + + + + diff --git a/docs/content/en/functions/templates.Exists.md b/docs/content/en/functions/templates.Exists.md new file mode 100644 index 000000000..36fa0ea60 --- /dev/null +++ b/docs/content/en/functions/templates.Exists.md @@ -0,0 +1,36 @@ +--- +title: templates.Exists +linktitle: "" +description: "Checks whether a template file exists under the given path relative to the `layouts` directory." +date: 2018-11-01 +publishdate: 2018-11-01 +lastmod: 2018-11-01 +categories: [functions] +tags: [] +menu: + docs: + parent: "functions" +ns: "" +keywords: ["templates", "template", "layouts"] +signature: ["templates.Exists PATH"] +workson: [] +hugoversion: "0.46" +aliases: [] +relatedfuncs: [] +toc: false +deprecated: false +--- + +A template file is any file living below the `layouts` directories of either the project or any of its theme components including partials and shortcodes. + +The function is particularly handy with dynamic path. The following example ensures the build will not break on a `.Type` missing its dedicated `header` partial. + +```go-html-template +{{ $partialPath := printf "headers/%s.html" .Type }} +{{ if templates.Exists ( printf "partials/%s" $partialPath ) }} + {{ partial $partialPath . }} +{{ else }} + {{ partial "headers/default.html" . }} +{{ end }} + +``` diff --git a/docs/content/en/functions/time.md b/docs/content/en/functions/time.md new file mode 100644 index 000000000..681c85fd9 --- /dev/null +++ b/docs/content/en/functions/time.md @@ -0,0 +1,62 @@ +--- +title: time +linktitle: +description: Converts a timestamp string into a `time.Time` structure. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [dates,time,location] +signature: ["time INPUT [TIMEZONE]"] +workson: [] +hugoversion: "v0.77.0" +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +`time` converts a timestamp string with an optional default location into a [`time.Time`](https://godoc.org/time#Time) structure so you can access its fields: + +``` +{{ time "2016-05-28" }} → "2016-05-28T00:00:00Z" +{{ (time "2016-05-28").YearDay }} → 149 +{{ mul 1000 (time "2016-05-28T10:30:00.00+10:00").Unix }} → 1464395400000, or Unix time in milliseconds +``` + +## Using Locations + +The optional `TIMEZONE` parameter is a string that sets a default time zone (or more specific, the location, which represents the collection of time offsets in a geographical area) that is associated with the specified time value. If the time value has an explicit timezone or offset specified, it will take precedence over the `TIMEZONE` parameter. + +The list of valid locations may be system dependent, but should include `UTC`, `Local`, or any location in the [IANA Time Zone database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). + +If no `TIMEZONE` is set, the `timeZone` from site configuration will be used. + +``` +{{ time "2020-10-20" }} → 2020-10-20 00:00:00 +0000 UTC +{{ time "2020-10-20" "America/Los_Angeles" }} → 2020-10-20 00:00:00 -0700 PDT +{{ time "2020-01-20" "America/Los_Angeles" }} → 2020-01-20 00:00:00 -0800 PST +``` + +## Example: Using `time` to get Month Index + +The following example takes a UNIX timestamp---set as `utimestamp: "1489276800"` in a content's front matter---converts the timestamp (string) to an integer using the [`int` function][int], and then uses [`printf`][] to convert the `Month` property of `time` into an index. + +The following example may be useful when setting up [multilingual sites][multilingual]: + +{{< code file="unix-to-month-integer.html" >}} +{{$time := time (int .Params.addDate)}} +=> $time = 1489276800 +{{$time.Month}} +=> "March" +{{$monthindex := printf "%d" $time.Month }} +=> $monthindex = 3 +{{< /code >}} + + +[int]: /functions/int/ +[multilingual]: /content-management/multilingual/ +[`printf`]: /functions/printf/ diff --git a/docs/content/en/functions/title.md b/docs/content/en/functions/title.md new file mode 100644 index 000000000..201e4c140 --- /dev/null +++ b/docs/content/en/functions/title.md @@ -0,0 +1,36 @@ +--- +title: title +# linktitle: +description: Converts all characters in the provided string to title case. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["title INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +--- + + +``` +{{title "BatMan"}}` → "Batman" +``` + +Can be combined in pipes. In the following snippet, the link text is cleaned up using `humanize` to remove dashes and `title` to convert the value of `$name` to Initial Caps. + +``` +{{ range $name, $items := .Site.Taxonomies.categories }} + <li><a href="{{ printf "%s/%s" "categories" ($name | urlize | lower) | absURL }}">{{ $name | humanize | title }} ({{ len $items }})</a></li> +{{ end }} +``` + +## Configure Title Case + +The default is AP Stylebook, but you can [configure it](/getting-started/configuration/#configure-title-case). diff --git a/docs/content/en/functions/transform.Unmarshal.md b/docs/content/en/functions/transform.Unmarshal.md new file mode 100644 index 000000000..9b380dc57 --- /dev/null +++ b/docs/content/en/functions/transform.Unmarshal.md @@ -0,0 +1,76 @@ +--- +title: "transform.Unmarshal" +description: "`transform.Unmarshal` (alias `unmarshal`) parses the input and converts it into a map or an array. Supported formats are JSON, TOML, YAML, XML and CSV." +date: 2018-12-23 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [] +signature: ["RESOURCE or STRING | transform.Unmarshal [OPTIONS]"] +hugoversion: "0.53" +aliases: [] +--- + +The function accepts either a `Resource` created in [Hugo Pipes](/hugo-pipes/) or via [Page Bundles](/content-management/page-bundles/), or simply a string. The two examples below will produce the same map: + +```go-html-template +{{ $greetings := "hello = \"Hello Hugo\"" | transform.Unmarshal }}` +``` + +```go-html-template +{{ $greetings := "hello = \"Hello Hugo\"" | resources.FromString "data/greetings.toml" | transform.Unmarshal }} +``` + +In both the above examples, you get a map you can work with: + +```go-html-template +{{ $greetings.hello }} +``` + +The above prints `Hello Hugo`. + +## CSV Options + +Unmarshal with CSV as input has some options you can set: + +delimiter +: The delimiter used, default is `,`. + +comment +: The comment character used in the CSV. If set, lines beginning with the comment character without preceding whitespace are ignored.: + +Example: + +```go-html-template +{{ $csv := "a;b;c" | transform.Unmarshal (dict "delimiter" ";") }} +``` + +## XML data + +As a convenience, Hugo allows you to access XML data in the same way that you access JSON, TOML, and YAML: you do not need to specify the root node when accessing the data. + +To get the contents of `<title>` in the document below, you use `{{ .message.title }}`: + +``` +<root> + <message> + <title>Hugo rocks!</title> + <description>Thanks for using Hugo</description> + </message> +</root> +``` + +The following example lists the items of an RSS feed: + +``` +{{ with resources.Get "https://example.com/rss.xml" | transform.Unmarshal }} + {{ range .channel.item }} + <strong>{{ .title | plainify | htmlUnescape }}</strong><br /> + <p>{{ .description | plainify | htmlUnescape }}</p> + {{ $link := .link | plainify | htmlUnescape }} + <a href="{{ $link }}">{{ $link }}</a><br /> + <hr> + {{ end }} +{{ end }} +``` diff --git a/docs/content/en/functions/trim.md b/docs/content/en/functions/trim.md new file mode 100644 index 000000000..7945ffef9 --- /dev/null +++ b/docs/content/en/functions/trim.md @@ -0,0 +1,41 @@ +--- +title: trim +# linktitle: +description: Returns a slice of a passed string with all leading and trailing characters from cutset removed. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["trim INPUT CUTSET"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +``` +{{ trim "++Batman--" "+-" }} → "Batman" +``` + +`trim` *requires* the second argument, which tells the function specifically what to remove from the first argument. There is no default value for the second argument, so **the following usage will not work**: + +``` +{{ trim .Inner}} +``` + +Instead, the following example tells `trim` to remove extra new lines from the content contained in the [shortcode `.Inner` variable][shortcodevars]: + +``` +{{ trim .Inner "\n" }} +``` + +{{% note %}} +Go templates also provide a simple [method for trimming whitespace](/templates/introduction/#whitespace) from either side of a Go tag by including a hyphen (`-`). +{{% /note %}} + + +[shortcodevars]: /variables/shortcodes/ diff --git a/docs/content/en/functions/truncate.md b/docs/content/en/functions/truncate.md new file mode 100644 index 000000000..8d0dd36b1 --- /dev/null +++ b/docs/content/en/functions/truncate.md @@ -0,0 +1,28 @@ +--- +title: truncate +# linktitle: truncate +description: Truncates a text to a max length without cutting words or leaving unclosed HTML tags. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [strings] +signature: ["truncate SIZE INPUT", "truncate SIZE ELLIPSIS INPUT"] +workson: [] +hugoversion: 19 +relatedfuncs: [] +deprecated: false +--- + +Since Go templates are HTML-aware, `truncate` will intelligently handle normal strings vs HTML strings: + +``` +{{ "<em>Keep my HTML</em>" | safeHTML | truncate 10 }}` → <em>Keep my …</em>` +``` + +{{% note %}} +If you have a raw string that contains HTML tags you want to remain treated as HTML, you will need to convert the string to HTML using the [`safeHTML` template function](/functions/safehtml) before sending the value to truncate. Otherwise, the HTML tags will be escaped when passed through the `truncate` function. +{{% /note %}} diff --git a/docs/content/en/functions/union.md b/docs/content/en/functions/union.md new file mode 100644 index 000000000..459e3620d --- /dev/null +++ b/docs/content/en/functions/union.md @@ -0,0 +1,49 @@ +--- +title: union +# linktitle: union +description: Given two arrays or slices, returns a new array that contains the elements or objects that belong to either or both arrays/slices. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-03-12 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [collections,intersect,union,complement] +signature: ["union SET1 SET2"] +workson: [] +hugoversion: 0.20 +relatedfuncs: [intersect,where] +deprecated: false +aliases: [] +--- + +Given two arrays (or slices) A and B, this function will return a new array that contains the elements or objects that belong to either A or to B or to both. The elements supported are strings, integers, and floats (only float64). + +``` +{{ union (slice 1 2 3) (slice 3 4 5) }} +<!-- returns [1 2 3 4 5] --> + +{{ union (slice 1 2 3) nil }} +<!-- returns [1 2 3] --> + +{{ union nil (slice 1 2 3) }} +<!-- returns [1 2 3] --> + +{{ union nil nil }} +<!-- returns an error because both arrays/slices have to be of the same type --> +``` + +## OR filter in where query + +This is also very useful to use as `OR` filters when combined with where: + +``` +{{ $pages := where .Site.RegularPages "Type" "not in" (slice "page" "about") }} +{{ $pages := $pages | union (where .Site.RegularPages "Params.pinned" true) }} +{{ $pages := $pages | intersect (where .Site.RegularPages "Params.images" "!=" nil) }} +``` + +The above fetches regular pages not of `page` or `about` type unless they are pinned. And finally, we exclude all pages with no `images` set in Page params. + +See [intersect](/functions/intersect) for `AND`. diff --git a/docs/content/en/functions/uniq.md b/docs/content/en/functions/uniq.md new file mode 100644 index 000000000..0a720f88f --- /dev/null +++ b/docs/content/en/functions/uniq.md @@ -0,0 +1,26 @@ +--- +title: uniq +linktitle: uniq +description: Takes in a slice or array and returns a slice with subsequent duplicate elements removed. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [multilingual,i18n,urls] +signature: ["uniq SET"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +aliases: [] +needsexamples: false +--- + +``` +{{ uniq (slice 1 2 3 2) }} +{{ slice 1 2 3 2 | uniq }} +<!-- both return [1 2 3] --> +``` diff --git a/docs/content/en/functions/unix.md b/docs/content/en/functions/unix.md new file mode 100644 index 000000000..98fcc74a4 --- /dev/null +++ b/docs/content/en/functions/unix.md @@ -0,0 +1,31 @@ +--- +title: .Unix +description: Converts a time.Time value to the number of seconds elapsed since the Unix epoch, excluding leap seconds. The Unix epoch is 00:00:00 UTC on 1 January 1970. +date: 2017-02-01 +keywords: [dates,time] +categories: [functions] +menu: + docs: + parent: "functions" +signature: [".Unix",".UnixMilli",".UnixMicro",".UnixNano"] +relatedfuncs: [Format,dateFormat,now,time] +--- + +The `Milli`, `Micro`, and `Nano` variants return the number of milliseconds, microseconds, and nanoseconds (respectively) elapsed since the Unix epoch. + +```go-html-template +.Date.Unix --> 1637259694 +.ExpiryDate.Unix --> 1672559999 +.Lastmod.Unix --> 1637361786 +.PublishDate.Unix --> 1637421261 + +("1970-01-01T00:00:00-00:00" | time.AsTime).Unix --> 0 +("1970-01-01T00:00:42-00:00" | time.AsTime).Unix --> 42 +("1970-04-11T01:48:29-08:00" | time.AsTime).Unix --> 8675309 +("2026-05-02T20:09:31-07:00" | time.AsTime).Unix --> 1777777771 + +now.Unix --> 1637447841 +now.UnixMilli --> 1637447841347 +now.UnixMicro --> 1637447841347378 +now.UnixNano --> 1637447841347378799 +``` diff --git a/docs/content/en/functions/upper.md b/docs/content/en/functions/upper.md new file mode 100644 index 000000000..0762541dd --- /dev/null +++ b/docs/content/en/functions/upper.md @@ -0,0 +1,28 @@ +--- +title: upper +# linktitle: upper +description: Converts all characters in a string to uppercase +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +keywords: [] +categories: [functions] +menu: + docs: + parent: "functions" +toc: +signature: ["upper INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +draft: false +aliases: [] +--- + +Note that `upper` can be applied in your templates in more than one way: + +``` +{{ upper "BatMan" }} → "BATMAN" +{{ "BatMan" | upper }} → "BATMAN" +``` diff --git a/docs/content/en/functions/urlize.md b/docs/content/en/functions/urlize.md new file mode 100644 index 000000000..82a88b9d7 --- /dev/null +++ b/docs/content/en/functions/urlize.md @@ -0,0 +1,73 @@ +--- +title: urlize +# linktitle: urlize +description: Takes a string, sanitizes it for usage in URLs, and converts spaces to hyphens. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [urls,strings] +signature: ["urlize INPUT"] +hugoversion: +deprecated: false +workson: [] +relatedfuncs: [] +--- + +The following examples pull from a content file with the following front matter: + +{{< code file="content/blog/greatest-city.md" copy="false">}} ++++ +title = "The World's Greatest City" +location = "Chicago IL" +tags = ["pizza","beer","hot dogs"] ++++ +{{< /code >}} + +The following might be used as a partial within a [single page template][singletemplate]: + +{{< code file="layouts/partials/content-header.html" download="content-header.html" >}} +<header> + <h1>{{.Title}}</h1> + {{ with .Params.location }} + <div><a href="/locations/{{ . | urlize}}">{{.}}</a></div> + {{ end }} + <!-- Creates a list of tags for the content and links to each of their pages --> + {{ with .Params.tags }} + <ul> + {{range .}} + <li> + <a href="/tags/{{ . | urlize }}">{{ . }}</a> + </li> + {{end}} + </ul> + {{ end }} +</header> +{{< /code >}} + +The preceding partial would then output to the rendered page as follows, assuming the page is being built with Hugo's default pretty URLs. + +{{< output file="/blog/greatest-city/index.html" >}} +<header> + <h1>The World's Greatest City</h1> + <div><a href="/locations/chicago-il">Chicago IL</a></div> + <ul> + <li> + <a href="/tags/pizza">pizza</a> + </li> + <li> + <a href="/tags/beer">beer</a> + </li> + <li> + <a href="/tags/hot-dogs">hot dogs</a> + </li> + </ul> +</header> +{{< /output >}} + + + +[singletemplate]: /templates/single-page-templates/ diff --git a/docs/content/en/functions/urls.Parse.md b/docs/content/en/functions/urls.Parse.md new file mode 100644 index 000000000..7709ad8c2 --- /dev/null +++ b/docs/content/en/functions/urls.Parse.md @@ -0,0 +1,31 @@ +--- +title: urls.Parse +description: Parse parses a given url, which may be relative or absolute, into a URL structure. +date: 2017-09-25 +publishdate: 2017-09-25 +lastmod: 2017-09-25 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [urls] +signature: ["urls.Parse URL"] +workson: [] +hugoversion: +deprecated: false +aliases: [] +--- + +`urls.Parse` takes a url as input + + +``` +{{ $url := urls.Parse "http://www.gohugo.io" }} +``` + +and returns a [URL](https://godoc.org/net/url#URL) structure. The struct fields are accessed via the `.` notation: + +``` +{{ $url.Scheme }} → "http" +{{ $url.Host }} → "www.gohugo.io" +``` diff --git a/docs/content/en/functions/where.md b/docs/content/en/functions/where.md new file mode 100644 index 000000000..f712cd984 --- /dev/null +++ b/docs/content/en/functions/where.md @@ -0,0 +1,176 @@ +--- +title: where +# linktitle: where +description: Filters an array to only the elements containing a matching value for a given field. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-02-01 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [filtering] +signature: ["where COLLECTION KEY [OPERATOR] MATCH"] +workson: [lists,taxonomies,terms,groups] +hugoversion: +relatedfuncs: [intersect,first,after,last] +deprecated: false +toc: true +needsexample: true +--- + +`where` filters an array to only the elements containing a matching +value for a given field. + +It works in a similar manner to the [`where` keyword in +SQL][wherekeyword]. + +```go-html-template +{{ range where .Pages "Section" "foo" }} + {{ .Content }} +{{ end }} +``` + +It can be used by dot-chaining the second argument to refer to a nested element of a value. + +``` ++++ +series: golang ++++ +``` + +```go-html-template +{{ range where .Site.Pages "Params.series" "golang" }} + {{ .Content }} +{{ end }} +``` + +It can also be used with the logical operators `!=`, `>=`, `in`, etc. Without an operator, `where` compares a given field with a matching value equivalent to `=`. + +```go-html-template +{{ range where .Pages "Section" "!=" "foo" }} + {{ .Content }} +{{ end }} +``` + +The following logical operators are available with `where`: + +`=`, `==`, `eq` +: `true` if a given field value equals a matching value + +`!=`, `<>`, `ne` +: `true` if a given field value doesn't equal a matching value + +`>=`, `ge` +: `true` if a given field value is greater than or equal to a matching value + +`>`, `gt` +: `true` if a given field value is greater than a matching value + +`<=`, `le` +: `true` if a given field value is lesser than or equal to a matching value + +`<`, `lt` +: `true` if a given field value is lesser than a matching value + +`in` +: `true` if a given field value is included in a matching value; a matching value must be an array or a slice + +`not in` +: `true` if a given field value isn't included in a matching value; a matching value must be an array or a slice + +`intersect` +: `true` if a given field value that is a slice/array of strings or integers contains elements in common with the matching value; it follows the same rules as the [`intersect` function][intersect]. + +## Use `where` with `Booleans` +When using booleans you should not put quotation marks. +```go-html-template +{{range where .Pages "Draft" true}} + <p>{{.Title}}</p> +{{end}} +``` + + +## Use `where` with `intersect` + +```go-html-template +{{ range where .Site.Pages "Params.tags" "intersect" .Params.tags }} + {{ if ne .Permalink $.Permalink }} + {{ .Render "summary" }} + {{ end }} +{{ end }} +``` + +You can also put the returned value of the `where` clauses into a variable: + +{{< code file="where-intersect-variables.html" >}} +{{ $v1 := where .Site.Pages "Params.a" "v1" }} +{{ $v2 := where .Site.Pages "Params.b" "v2" }} +{{ $filtered := $v1 | intersect $v2 }} +{{ range $filtered }} +{{ end }} +{{< /code >}} + +## Use `where` with `first` + +Using `first` and `where` together can be very +powerful. Below snippet gets a list of posts only from [**main +sections**](#mainsections), sorts it using the [default +ordering](/templates/lists/) for lists (i.e., `weight => date`), and +then ranges through only the first 5 posts in that list: + +{{< code file="first-and-where-together.html" >}} +{{ range first 5 (where site.RegularPages "Type" "in" site.Params.mainSections) }} + {{ .Content }} +{{ end }} +{{< /code >}} + +## Nest `where` Clauses + +You can also nest `where` clauses to drill down on lists of content by more than one parameter. The following first grabs all pages in the "blog" section and then ranges through the result of the first `where` clause and finds all pages that are *not* featured: + +```go-html-template +{{ range where (where .Pages "Section" "blog" ) "Params.featured" "!=" true }} +``` + +## Unset Fields + +Filtering only works for set fields. To check whether a field is set or exists, you can use the operand `nil`. + +This can be useful to filter a small amount of pages from a large pool. Instead of setting a field on all pages, you can set that field on required pages only. + +Only the following operators are available for `nil` + +* `=`, `==`, `eq`: True if the given field is not set. +* `!=`, `<>`, `ne`: True if the given field is set. + +```go-html-template +{{ range where .Pages "Params.specialpost" "!=" nil }} + {{ .Content }} +{{ end }} +``` + +## Portable `where` filters -- `site.Params.mainSections` {#mainsections} + +**This is especially important for themes.** + +To list the most relevant pages on the front page or similar, you +should use the `site.Params.mainSections` list instead of comparing +section names to hard-coded values like `"posts"` or `"post"`. + +```go-html-template +{{ $pages := where site.RegularPages "Type" "in" site.Params.mainSections }} +``` + +If the user has not set this config parameter in their site config, it +will default to the _section with the most pages_. + +The user can override the default: + +{{< code-toggle file="config" >}} +[params] + mainSections = ["blog", "docs"] +{{< /code-toggle >}} + +[intersect]: /functions/intersect/ +[wherekeyword]: https://www.techonthenet.com/sql/where.php diff --git a/docs/content/en/functions/with.md b/docs/content/en/functions/with.md new file mode 100644 index 000000000..ae643caf7 --- /dev/null +++ b/docs/content/en/functions/with.md @@ -0,0 +1,34 @@ +--- +title: with +# linktitle: with +description: Rebinds the context (`.`) within its scope and skips the block if the variable is absent or empty. +date: 2017-02-01 +publishdate: 2017-02-01 +lastmod: 2017-03-12 +categories: [functions] +menu: + docs: + parent: "functions" +keywords: [conditionals] +signature: ["with INPUT"] +workson: [] +hugoversion: +relatedfuncs: [] +deprecated: false +--- + +An alternative way of writing an `if` statement and then referencing the same value is to use `with` instead. `with` rebinds the context (`.`) within its scope and skips the block if the variable is absent, unset or empty. + +The set of *empty* values is defined by [the Go templates package](https://golang.org/pkg/text/template/). Empty values include `false`, the number zero, and the empty string. + +If you want to render a block if an index or key is present in a slice, array, channel or map, regardless of whether the value is empty, you should use [`isset`](/functions/isset) instead. + +The following example checks for a [user-defined site variable](/variables/site/) called `twitteruser`. If the key-value is not set, the following will render nothing: + +{{< code file="layouts/partials/twitter.html" >}} +{{with .Site.Params.twitteruser}}<span class="twitter"> +<a href="https://twitter.com/{{.}}" rel="author"> +<img src="/images/twitter.png" width="48" height="48" title="Twitter: {{.}}" + alt="Twitter"></a> +</span>{{end}} +{{< /code >}} |