Range over string slice in golang template
Asked Answered
O

2

23

I have a struct that contains a slice of type string like the following.

 type Data struct {
      DataFields []string
 }

Within my html template file I would like to range over the string slice. However, the individual fields are just strings without any struct name. How can I loop over a slice that contains a simple type such as string, int, etc?

Orme answered 12/1, 2019 at 1:49 Comment(0)
L
36

Or assign it to a variable, similar to a normal Go range clause:

 {{range $element := .DataFields}} {{$element}} {{end}}

Run it on the Playground

From the docs for text/template (serves as interface docs for html/template):

{{range pipeline}} T1 {{end}}
    The value of the pipeline must be an array, slice, map, or channel.
    If the value of the pipeline has length zero, nothing is output;
    otherwise, dot is set to the successive elements of the array,
    slice, or map and T1 is executed. If the value is a map and the
    keys are of basic type with a defined order ("comparable"), the
    elements will be visited in sorted key order.

...

A pipeline inside an action may initialize a variable to capture the result. The initialization has syntax

$variable := pipeline

...

If a "range" action initializes a variable, the variable is set to the successive elements of the iteration. Also, a "range" may declare two variables, separated by a comma:

range $index, $element := pipeline

in which case $index and $element are set to the successive values of the array/slice index or map key and element, respectively. Note that if there is only one variable, it is assigned the element; this is opposite to the convention in Go range clauses.

(bold portions emphasized by me)

Lythraceous answered 12/1, 2019 at 20:50 Comment(0)
J
38

Use . to refer to a simple values like a string, int, etc.

 {{range .DataFields}}{{.}}{{end}}

Run it on the Playground.

You can also assign to a template variable as in {{range $v := .DataFields}}{{$v}}{{end}}, but that's extra work. Embrace the ..

Jollification answered 12/1, 2019 at 2:12 Comment(1)
Personally, the second syntax, {{range $v := .DataFields}}{{$v}}{{end}} provides a significant benefit in readability for a few more characters on the screen. I'll take that tradeoff!Martineau
L
36

Or assign it to a variable, similar to a normal Go range clause:

 {{range $element := .DataFields}} {{$element}} {{end}}

Run it on the Playground

From the docs for text/template (serves as interface docs for html/template):

{{range pipeline}} T1 {{end}}
    The value of the pipeline must be an array, slice, map, or channel.
    If the value of the pipeline has length zero, nothing is output;
    otherwise, dot is set to the successive elements of the array,
    slice, or map and T1 is executed. If the value is a map and the
    keys are of basic type with a defined order ("comparable"), the
    elements will be visited in sorted key order.

...

A pipeline inside an action may initialize a variable to capture the result. The initialization has syntax

$variable := pipeline

...

If a "range" action initializes a variable, the variable is set to the successive elements of the iteration. Also, a "range" may declare two variables, separated by a comma:

range $index, $element := pipeline

in which case $index and $element are set to the successive values of the array/slice index or map key and element, respectively. Note that if there is only one variable, it is assigned the element; this is opposite to the convention in Go range clauses.

(bold portions emphasized by me)

Lythraceous answered 12/1, 2019 at 20:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.