I need to use text/template to template a file over successive iterations. Initially not all data values will be present but on later iterations more and more data values will exist.
Currently, values not found in the data supplied to Template.Execute() are replaced depending on the active option (set via Template.Option()). By default the following template:
ID={{ .Id }}, Name={{ .Name }}
will be templated as:
ID=<no value>, Name=Bob
if executed with
data := map[string]interface{}{
"Name": "Bob",
}
But I need it to return:
ID={{ .Id }}, Name=Bob
Adding a 'missingkey=ignore' option that would preserve the original tag in templated output if keys are missing from the data supplied when executing a template. I.e. the above template would return:
ID={{ .Id }}, Name=Bob
if executed with
data := map[string]interface{}{
"Name": "Bob",
}
This is a duplicate of #23488 but with a different use case.
@mvdan @robpike
For an implementation see: https://github.com/sugarkube/texttemplate/
What if Bob's name is not "Bob" but "{{.Id}}"?
This seems the same use case as #23488 and it has the same problem: you can't tell what is "unsubstituted" and what is "substituted but looks like template anyway".
My inclination would be to close this for exactly the same reasons as #23488.
What if Bob's name is not "Bob" but "{{.Id}}"?
That should be fully supported behaviour, allowing more complex progressive rendering. E.g.
Name={{ .Name }} -> Name={{ .FullName }} -> Name=Bob Jones
The library would neither need to know nor care that {{ .Name }} was replaced by {{ .FullName }}. On a subsequent pass {{ .FullName }} could be replaced by the corresponding value in a map.
When iteratively rendering templates it'd make sense to be defensive anyway, which would probably mean rendering in several passes - the first x times with this option enabled and finally with it disabled to mop up any outstanding tags.
I don't see why we the library shouldn't include this functionality just because there may be edge cases that cause errors - that applies to most parts of various libraries anyway. This feature would open up additional possibilities though.
Sorry, but no. This kind of ambiguity about what's the original text and what is substitution is how you end up with "little Bobby tables" problems.
This ambiguity is basically also the same problem as unintended variable capture in macro systems. There is no question that it is powerful to be able to do this - see the entirety of On Lisp, for example - but it also creates many many subtle problems - see all the follow-on papers about hygienic macros in Scheme.
Go is aiming for clear and easy to understand. Especially since most users of templating are using html/template, where original template is trusted more than substituted text, it is critically important to avoid the ambiguity about what came from the original template and what did not. This feature would almost certainly lead to security problem after security problem when used.
Most helpful comment
What if Bob's name is not
"Bob"but"{{.Id}}"?This seems the same use case as #23488 and it has the same problem: you can't tell what is "unsubstituted" and what is "substituted but looks like template anyway".
My inclination would be to close this for exactly the same reasons as #23488.