6

Is there a simple way like template.ParseFiles("base.html", "home.html") but for strings to build a template from a set of strings?

I have a base template and a list of pages templates (all as strings) that I want to build on top of base template.

I figured out how to merge them, but I my solution is quite verbose and doesn't look elegant enough, even though working.

icza
  • 389,944
  • 63
  • 907
  • 827
Sergei Basharov
  • 51,276
  • 73
  • 200
  • 335

2 Answers2

7

You may create a new, empty template using template.New() function. Then you may use the Template.New() method to create a new, empty, associated template. And you may parse "into" this using the Template.Parse() method.

Here's how it could look like:

func parseTemplates(templs ...string) (t *template.Template, err error) {
    t = template.New("_all")

    for i, templ := range templs {
        if _, err = t.New(fmt.Sprint("_", i)).Parse(templ); err != nil {
            return
        }
    }

    return
}

Testing it:

t, err := parseTemplates(
    `{{define "one"}}I'm #1.{{end}}`,
    `{{define "two"}}I'm #2, including #1: {{template "one" .}}{{end}}`,
)
if err != nil {
    panic(err)
}

if err = t.ExecuteTemplate(os.Stdout, "two", nil); err != nil {
    panic(err)
}

Output (try it on the Go Playground):

I'm #2, including #1: I'm #1.

Also see related question: Go template name

Note

While we could call the Template.Parse() method on a single template multiple times, and it would parse multiple named templates properly, it is still advisable to acquire a new template.Template for each by calling Template.New(). Because if the template texts have content outside of named templates, they will be overwritten and only the last would be retained. For example: abc {{define "one"}}no 1{{end}}. The static text "abc" would be lost by a subsequent Template.Parse() call.

This is also noted in the doc of Template.Parse():

(In multiple calls to Parse with the same receiver template, only one call can contain text other than space, comments, and template definitions.)

Community
  • 1
  • 1
icza
  • 389,944
  • 63
  • 907
  • 827
0

Maybe

for _, templ := range ListOfPagesTemplates{
    YourBaseTemplate.Parse(templ)
}

err check absent for simplicity of reading

Uvelichitel
  • 8,220
  • 1
  • 19
  • 36
  • 1
    While this may be used to parse multiple _named_ templates, without acquiring a new `template.Template` for each by calling `Template.New()`, if the template texts have content _outside_ of named templates, they will be overwritten and only the last will be retained. Example: `abc {{define "one"}}no 1{{end}}`. The static text `"abc"` would be lost by a subsequent `Parse()`. See my answer for details. – icza Jan 25 '17 at 16:48
  • @icza Yes, your answer is more exact and detailed for sure. I only show the way it can be done. – Uvelichitel Jan 25 '17 at 17:00