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.

2 Answers 2

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.)

Sign up to request clarification or add additional context in comments.

Comments

0

Maybe

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

err check absent for simplicity of reading

2 Comments

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 Yes, your answer is more exact and detailed for sure. I only show the way it can be done.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.