I'm a newbie Go (and Go templates) amateur programmer, and I have seen variants of this question being asked, but never quite in the same way, so here it goes again...
I'm attempting to do the following without registering any additional functions (so, limiting myself strictly to what the limited template syntax allows):
Suppose I have several different snippets of HTML, each on its own template: A.tpl
, B.tpl
, C.tpl
and so forth (the number is not fixed, and it will grow over time as the application grows; also, there is no implicit numbering/sequential naming in the subtemplates as the example may imply).
Then I have a main template which sets the common headers, footers, menus and so forth, as well as the necessary HTML wrapping around each, in main.tpl
, something very simple like this:
{{ if .A }}
{{ template "A.tpl" . }}
{{ end }}
{{ if .B }}
{{ template "B.tpl" . }}
{{ end }}
{{ if .C }}
{{ template "C.tpl" . }}
{{ end }}
...
or, depending on how the calling code has been done, this could also be written as (assuming we're passing the name of the subtemplate as a value to main.tpl
):
{{ if eq .SubTemplate "A.tpl" }}
{{ template "A.tpl" . }}
{{ end }}
{{ if eq .SubTemplate "B.tpl" }}
{{ template "B.tpl" . }}
{{ end }}
{{ if eq .SubTemplate "C.tpl" }}
{{ template "C.tpl" . }}
{{ end }}
...
Clearly, what would be obvious to write (at the template level) would be:
{{ template .SubTemplate . }}
but of course that is syntactically invalid, because template
can only use a string constant, not a value/variable, as a parameter (right?)
The reasoning behind forcing a long list of if
statements on the templates seems to be that this kind of programming style is deemed to be 'logic' which ought to be taken out of templates, at least at a 'standard' level of the language; Go programmers are supposed not to think on the template engine (= presentation layer) as having any intrinsic 'logic' in it. Of course, it's not up to me to discuss what is considered logic and what isn't (an if
statement that is allowed to test for equality on specific values and executes different blocks depending on those values is most certainly 'logic' for me, but apparently not for the Go developers).
Similar questions were asked a few years ago and the answer was never very satisfactory for the OP. Basically, as far as I understood it, there are a few choices:
- Define a new function, extending the template code, that eventually creates the equivalent a switch statement; this would allow at least saving a few
{{ if ... end }}
constructs, but, for me, it would still lack the simplicity and readability of a one-liner. - Hacking (or, rather, extending...) the whole
html/template
package to change the template syntax, something which allegedly has been done by @Intermernet four years ago. It's a valid exercise, of course, but it means getting away from a standard Go library. If that's the choice, then there are plenty of template engines for Go around there; I'm just reluctant in starting to use one of them and find out after a couple of years that it became obsolete because the authors have abandoned the project. With standard libraries that will not happen (at least while Google is around and Ken Thompson is still alive). - Doing all the processing of what subtemplate to use on the Go side. This is naturally feasible, but (IMHO) it leads to much less readable code. Of course, I'm aware of the ideological battles among Go programmers, between those who are keen on writing 'idiomatic' (but hard-to-follow) code, and the many other factions who have different ways of writing Go code. Personally, I adhere to the Principle of Least Surprise and KISS — I want my own code to be understandable even ten years after I have written it :)
Has the template syntax evolved towards allowing what I've described (and I was just unfortunate enough not to have found any working example), or am I still stuck to complexify the Go code, or use a different, non-standard Go templating engine to accomplish this simple task?
Thank you all in advance for any insights you might have. I'm still crossing my fingers hoping that I'm just too much of a newbie with the Go template syntax and that it actually allows what I want, I just need to add a few more awkward symbols to allow the template
keyword to accept a variable instead of a string constant, something which, so far, has eluded me :-)