Description
Many template languages offer a directive at the top of a template files to say which template to use as a "base". This does not fit the model of templates that Go uses.
Currently, template inheritance in Go requires the program executing the templates to clone or reparse the template files in order to allow a "base" template to provide alternate definitions of the required associated templates. This can be inflexible in practice and requires that the program executing the templates be aware of the template hierarchy.
I propose the template action "extend".
{{extend "name"}}Ds{{end}}
{{extend "name" pipeline}}Ds{{end}}
The Ds
are zero or more template definitions (anything other than define actions is an error, whitespace is ignored). These template definitions only exist within the extend
block, not in the global namespace.
With zero Ds
, extend
is exactly the same as the equivalent template
action.
When one or more Ds
are provided, extend
executes the named template overriding any global template definitions with those in Ds
.
Essentially it let's you pass both the data and the templates to use to another template, most likely to override blocks.
For a web page, this might look something like:
"welcome.html"
{{extend "layout.html" .}}
{{define "title"}}Welcome{{end}}
{{define "body"}}
<p>Hello, world</p>
{{end}}
{{end}}
"about.html"
{{extend "layout.html" .}}
{{define "title"}}About us{{end}}
{{define "body"}}
<p>We make great template examples.</p>
{{end}}
{{end}}
The contents of "layout.html" are largely irrelevant, other than that it may invoke templates named "title" and "body".
The program using these templates does not need to do anything special to allow "welcome.html" and "about.html" to both redefine the same templates in "layout.html": it only has to ParseGlob("templates/*.html")
and ExecuteTemplate either "welcome.html" or "about.html", as appropriate.
It does not even need to be aware of the shared "layout.html".
If, later, a certain subset of pages need to extend a different base template, no changes are required of the program—only to the templates that need to be updated.
While a bit more verbose than other template languages, this fits well with how other template languages handle similar problems, lessening the learning curve of Go templates.
It's also a more powerful and general mechanism since it is just an ordinary template action and not a special directive, allowing for finer-grained reuse.