It depends on what your data is.
I want to categorise this.
- Primary data that the template is meant for. In your example that would be Invoice/Invoicelist. If you have to pass more than one of these you have to reconsider your template design.
- Secondary data such as logged in user information or any common information that you find yourself passing into several templates.
Since these information are common. I usually make them into functions. Since these functions cannot have input params. You might want to create them as closures (within another function). Assign these function to funMap and add it to the template after parsing.
func MakeFuncMap(u *user) map[string]interface{} {
return map[string]interface{}{
"User": func() *user {return u}, //Can be accessed by "User." within your template
}
}
t, err := template.New("tmpl").Funcs(MakeFuncMap(nil)).Parse("template") //You will need to append a dummy funcMap as you will not have access to User at the time of template parsing
//You will have to clone the template to make it thread safe to append funcMap.
tClone, _ := t.Clone()
tClone.Funcs(MakeFuncMap(u)).Execute(w, invoicelist)
Now you can execute the template with only the invoicelist as data.
Within your template you should be able to access user information using "User." and invoice list by "."
You should be able to define the funcMap once for all the common data. So that you will be able reuse it.
To loop through a invoicelist you can look into range
{{range .}} //if you are passing invoicelist then the . means invoicelist
//in here . means each of the invoice
<label>{{User.Name}}, {{User.Age}}</label>
<label>{{.Id}}</label>
{{end}}
EDIT: Included fix for issue pointed out by Ripounet