Reputation: 1072
I have the following case, where I am passing a struct containing a map to a template:
package main
import (
"log"
"os"
"text/template"
)
var fns = template.FuncMap{
"plus1": func(x int) int {
return x + 1
},
}
type codec struct {
Names map[string]string
Count int
}
func main() {
a := map[string]string{"one": "1",
"two": "2",
"three": "3"}
t := template.Must(template.New("abc").Funcs(fns).Parse(`{{$l := len .Names}}{{range $k, $v := .Names}}{{if ne (plus1 $.Count) $l}}{{$k}} {{$v}} {{end}}{{end}}.`))
err := t.Execute(os.Stdout, codec{a, 0})
if err != nil {
log.Println(err)
}
}
I would like to increment the Count
field of codec
so that I can know how many items of the map I've seen.
Upvotes: 1
Views: 1570
Reputation: 418137
You can simply define a method on your struct:
type codec struct {
Names map[string]string
Count int
}
func (c *codec) IncAndGet() int {
c.Count++
return c.Count
}
Calling it from a template:
c := &codec{Count: 2}
t := template.Must(template.New("").Parse(`{{.IncAndGet}} {{.IncAndGet}}`))
t.Execute(os.Stdout, c)
Output (try it on the Go Playground):
3 4
Note that for this to work, the method needs a pointer receiver (func (c *codec) IncAndGet()
) and you have to pass a pointer to Template.Execute()
(c
is a pointer in our example: c := &codec{Count: 2}
).
If you don't want any result just counting, define it to have a string
return type and return the empty string
""
:
func (c *codec) Inc() string {
c.Count++
return ""
}
Upvotes: 1
Reputation: 49235
One solution is to make the plus1
function a closure that acts directly on the value of the codec
:
// first create a codec instance
c := codec {a, 0}
// now define the function as a closure with a reference to c
fns := template.FuncMap{
"plus1": func() int {
c.Count++
return c.Count
},
}
// now we don't need to pass anything to it in the template
t := template.Must(template.New("abc").Funcs(fns).Parse(`{{$l := len .Names}}{{range $k, $v := .Names}}{{if ne (plus1) $l}}{{$k}} {{$v}} {{end}}{{end}}.`))
The output was:
one 1 three 3
which I'm guessing is what you were aiming for? And the value is retained in c
at the end of execution.
Upvotes: 2