1

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:

  1. 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.
  2. 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).
  3. 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 :-)

Gwyneth Llewelyn
  • 796
  • 1
  • 11
  • 27
  • 1
    Support for `{{ template .SubTemplate . }}` was removed [in this commit](https://github.com/golang/go/commit/7aa1a1a64d8f43a33b41f67a5c9366b3d8b67328). It's unclear from the comment why support for the feature was removed, but it may be because work was already underway on the contextual escaper where supporting this feature is difficult or impossible. – Charlie Tumahai Jul 08 '17 at 14:25
  • 1
    This is not possible, as contex may vary on the including template. See more explanation in the marked duplicate. Multiple solutions (workarounds) are listed there, I suggest template refactoring; e.g. have different templates for different pages, and have them include header and footer, instead of a "master" template including various page content based on the page name. – icza Jul 08 '17 at 16:39
  • Thank you for your answers. It seems that I have missed this very same question before: https://stackoverflow.com/questions/28830543/how-to-use-a-field-of-struct-or-variable-value-as-template-name where the answer, as you both said, is negative — this is simply something that cannot be done. – Gwyneth Llewelyn Jul 11 '17 at 10:08

0 Answers0