range
Syntax
The collection may be a slice, a map, or an integer.
{{ $s := slice "foo" "bar" "baz" }}
{{ range $s }}
{{ . }} → foo bar baz
{{ end }}Use with the else statement:
{{ $s := slice "foo" "bar" "baz" }}
{{ range $s }}
<p>{{ . }}</p>
{{ else }}
<p>The collection is empty</p>
{{ end }}Within a range block:
- Use the
continuestatement to stop the innermost iteration and continue to the next iteration - Use the
breakstatement to stop the innermost iteration and bypass all remaining iterations
Understanding context
See the context section in the introduction to templating.
For example, at the top of a page template, the context (the dot) is a Page object. Within the range block, the context is bound to each successive element.
With this contrived example:
{{ $s := slice "foo" "bar" "baz" }}
{{ range $s }}
{{ .Title }}
{{ end }}Hugo will throw an error:
can't evaluate field Title in type intThe error occurs because we are trying to use the .Title method on a string instead of a Page object. Within the range block, if we want to render the page title, we need to get the context passed into the template.
Use the $ to get the context passed into the template.
This template will render the page title three times:
{{ $s := slice "foo" "bar" "baz" }}
{{ range $s }}
{{ $.Title }}
{{ end }}Gaining a thorough understanding of context is critical for anyone writing template code.
Examples
Slice of scalars
This template code:
{{ $s := slice "foo" "bar" "baz" }}
{{ range $s }}
<p>{{ . }}</p>
{{ end }}Is rendered to:
<p>foo</p>
<p>bar</p>
<p>baz</p>This template code:
{{ $s := slice "foo" "bar" "baz" }}
{{ range $v := $s }}
<p>{{ $v }}</p>
{{ end }}Is rendered to:
<p>foo</p>
<p>bar</p>
<p>baz</p>This template code:
{{ $s := slice "foo" "bar" "baz" }}
{{ range $k, $v := $s }}
<p>{{ $k }}: {{ $v }}</p>
{{ end }}Is rendered to:
<p>0: foo</p>
<p>1: bar</p>
<p>2: baz</p>Slice of maps
This template code:
{{ $m := slice
(dict "name" "John" "age" 30)
(dict "name" "Will" "age" 28)
(dict "name" "Joey" "age" 24)
}}
{{ range $m }}
<p>{{ .name }} is {{ .age }}</p>
{{ end }}Is rendered to:
<p>John is 30</p>
<p>Will is 28</p>
<p>Joey is 24</p>Slice of pages
This template code:
{{ range where site.RegularPages "Type" "articles" }}
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
{{ end }}Is rendered to:
<h2><a href="/articles/article-3/">Article 3</a></h2>
<h2><a href="/articles/article-2/">Article 2</a></h2>
<h2><a href="/articles/article-1/">Article 1</a></h2>Maps
This template code:
{{ $m := dict "name" "John" "age" 30 }}
{{ range $k, $v := $m }}
<p>key = {{ $k }} value = {{ $v }}</p>
{{ end }}Is rendered to:
<p>key = age value = 30</p>
<p>key = name value = John</p>Unlike ranging over an array or slice, Hugo sorts by key when ranging over a map.
Integers
New in v0.123.0Ranging over a positive integer n executes the block n times, with the context starting at zero and incrementing by one in each iteration.
{{ $s := slice }}
{{ range 1 }}
{{ $s = $s | append . }}
{{ end }}
{{ $s }} → [0]{{ $s := slice }}
{{ range 3 }}
{{ $s = $s | append . }}
{{ end }}
{{ $s }} → [0 1 2]Ranging over a non-positive integer executes the block zero times.
See Go’s text/template documentation for more information.
