Reputation: 5053
I am working in Go, and right now I need to print at least 20 options inside a select, so I need to use some kind of loop that goes from 0 to 20 (to get an index).
How can I use a for loop inside a Go template?
I need to generate the sequence of numbers inside the template. I don't have any array to iterate.
EDIT: I need to get something like this:
<select>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
So, I need to do in the code something like:
<select>
{{for i := 1; i < 5; i++}}
<option value="{{i}}">{{i}}</option>
{{end}}
</select>
But, this doesn't work.
Upvotes: 28
Views: 69509
Reputation: 1316
You can use range
in templates as well. See https://golang.org/pkg/text/template/#hdr-Variables
Easiest option might be to just use a slice containing your options:
func main() {
const tmpl = `
<select>
{{range $val := .}}
<option value="{{$val}}">{{$val}}</option>
{{end}}
</select>
`
t := template.Must(template.New("tmpl").Parse(tmpl))
t.Execute(os.Stdout, []int{1, 2, 3})
}
Upvotes: 31
Reputation: 11
You can also use a channel to avoid building a slice:
funcMap := template.FuncMap{
"loop": func(from, to int) <-chan int {
ch := make(chan int)
go func() {
for i := from; i <= to; i++ {
ch <- i
}
close(ch)
}()
return ch
},
}
then:
{{range $x := loop 3 9 }}
Hey {{$x}}!
{{- end}}
See the full working example: https://go.dev/play/p/DP2WuROnCC9
Upvotes: 1
Reputation: 1482
Your best bet is to add an "Iterate" function to your func_map.
template.FuncMap{
"Iterate": func(count *uint) []uint {
var i uint
var Items []uint
for i = 0; i < (*count); i++ {
Items = append(Items, i)
}
return Items
},
}
Once you register your function map with text/template, you can iterate like this:
{{- range $val := Iterate 5 }}
{{ $val }}
{{- end }}
I don't know why this useful function isn't part of the default set of functions text/template provides. Maybe they'll add something similar in the future.
Upvotes: 16