Do you know what exactly associated template is? It’s one of the concepts that confused me a lot. This post explains what associated template is in detail.

I’ll use a term “template group” in order to explain what associated template is. The term is not in the official godoc.

template.New()

When you create a template with template.New(),

t1 := template.New("t1")

a template object is created with the name specified. At the same time, a template group is created.

A template group is a object with a FuncMap and a list of Template that the group has. (The list is implemented as a map internally, but it’s shown as a list for brevity)

At this point, t1 is not in the template list yet. When you call Parse(),

t1.Parse(...)

“t1” is added to the template list.

Associate a template with t.New()

When you call the following,

t2, err := t1.New("t2").Parse(...) t3, err := t1.New("t3").Parse(...)

it creates the following structure.

t1, t2 and t3 are all members of the same group. They share FuncMap and the template list.

Godoc of t.New(name string) says.

New allocates a new template associated with the given one and with the same delimiters. The association, which is transitive, allows one template to invoke another with a {{template}} action.

It’s easy to understand what the godoc means with the above diagram. When templates are associated, they are in the same group.

Name of a Template

Each template has a name. It’s not allowed to add more than one templates to the template list by calling Parse().

Template name need to be unique in a group. It’s OK to have templates with the same name if they belong to different groups.

tA,err := template.New("t1").Parse(...) tB,err := template.New("t1").Parse(...)

t.Lookup()

t.Lookup(name string) finds the template by name in a group.

You can use any receiver objects to find a template. Following three codes return the same template object.

t1.Lookup("t3") // returns t3 t2.Lookup("t3") // returns t3 t3.Lookup("t3") // returns t3

t.Templates()

t.Templates() returns a copy of the list of templates in the group.

All of the following codes return lists with the same contents.

t1.Templates() t2.Templates() t3.Templates()

Difference between t.Execute() and t.ExecuteTemplate()

t.Execute() uses the template t itself.

t1.Execute(w, obj)

t.ExecuteTemplate() looks up a template by name, and execute the looked-up template.

t1.ExecuteTemplate(w, "t3", obj)

Following three codes are equivalent.

t1.ExecuteTemplate(w, "t3", obj) // = t3.Execute(w, obj) t2.ExecuteTemplate(w, "t3", obj) // = t3.Execute(w, obj) t3.ExecuteTemplate(w, "t3", obj) // = t3.Execute(w, obj)

What template.ParseFiles() does

template.ParseFiles() creates templates and put all of them in a same group.

t, err := template.ParseFiles("a/go.tmpl", "b/lang.tmpl", "c/rocks.tmpl")

creates following structure.

Name of each templates is a base name of the file.

The returned template is the first template created. In the above code, the template with the name “go.tmpl” is returned.