MisutoWolf
MisutoWolf

Reputation: 1233

Parsing Multiple Templates in Go

I'm trying to figure out how to go about loading multiple templates in Go when a lot of them have a similar....base, you could say?

Currently, I've got the following two templates I'm loading in a sample application I'm working on:

homeTemplate, err = template.ParseFiles(
    "views/layout/base.gohtml",
    "views/layout/menu.html",
    "views/layout/footer.gohtml",
    "views/home.gohtml")
if err != nil {
    panic(err)
}

contactTemplate, err = template.ParseFiles(
    "views/layout/base.gohtml",
    "views/layout/menu.html",
    "views/layout/footer.gohtml",
    "views/contact.gohtml")
if err != nil {
    panic(err)
}

My question is the following:

Is there a way to set this up in such a way that I can store the first three entries in each list of templates in a variable and then just append the final inclusion at the end so I can shorten the amount of code and simplify things?

Am I tackling this whole thing wrong? I read somewhere about using a setup that incorporated a template["name"] syntax and then rendering from that, maybe I just need to load the base templates before the rest of this stuff, since they're more of less for layout stuff, and they probably don't need to be part of the above variables?

Upvotes: 2

Views: 4352

Answers (2)

icza
icza

Reputation: 418745

One option is to use Template.Clone() as you can see in mkopriva's answer. Note that Template.Clone() does not copy the actual representation of the templates, the clone will share the representation with the original.

Another option is to parse all template files in one step, so the "base" templates will obviously will only be parsed once:

all := template.Must(template.ParseFiles(
    "views/layout/base.gohtml",
    "views/layout/menu.html",
    "views/layout/footer.gohtml",
    "views/home.gohtml",
    "views/contact.gohtml",
))

And you can use Template.ExecuteTemplate() to execute a designated, named template, e.g.:

// To execute the home template:
err := all.ExecuteTemplate(w, "home.gohtml", params)

// To execute the contact template:
err := all.ExecuteTemplate(w, "contact.gohtml", params)

Pros of using Template.Clone() is that you can have multiple templates with the same name, which would not work when loading all at once.

Pros of loading all at once is that it's simpler.

Upvotes: 2

mkopriva
mkopriva

Reputation: 38343

https://golang.org/pkg/html/template/#Template.Clone

Clone can be used to prepare common templates and use them with variant definitions for other templates by adding the variants after the clone is made.

baseTemplate, err = template.ParseFiles(
    "views/layout/base.gohtml",
    "views/layout/menu.html",
    "views/layout/footer.gohtml")
if err != nil {
    panic(err)
}

homeTemplate, err = template.Must(baseTemplate.Clone()).ParseFiles("views/home.gohtml")
if err != nil {
    panic(err)
}

contactTemplate, err = template.Must(baseTemplate.Clone()).ParseFiles("views/contact.gohtml")
if err != nil {
    panic(err)
}

https://play.golang.org/p/q9ox01W8U00

Upvotes: 3

Related Questions