-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
text/template: support lexically scoped variables? #14992
Comments
Just as an additional info, while jinja2 has similar scoping it seems to have many possible ways of still doing this task: http://stackoverflow.com/questions/4870346/can-a-jinja-variables-scope-extend-beyond-in-an-inner-block I agree they aren't specifically pretty, but maybe Go Template could be one of the first to actually allow this properly? Suggestion on the syntax: Maybe add something like |
As you've noticed, the template package was not designed to be a programming language in its own right. In fact, that is a non-goal of the package. If we were to go down this road, where would it end? Once you give people the essential primitives for implementing algorithms in the template language, they will thirst for more. At some point you end up implementing a new language or re-implementing a weird version of Go. I hope you can appreciate that this is not a minor issue, but rather a fundamental design decision. I know this is an unsatisfying answer for you.
If the author of the program expects their users to write template code then they should provide a set of useful template functions and methods on their data types to make these common tasks possible. Or they may choose a different template package that permits this kind of programming. Do you have a specific use case in mind? What is the application you are writing templates for? |
More info on my use case: The application: https://github.com/jwilder/docker-gen I see two solution possibilities for Go Template: 1. Global variables as specified As described in this feature request's initial post. Also, where would it end? Exactly here. Just add proper global scope variable support. Again jinja2 and others already support this with workarounds, the major problem of Go Template is that there appear to be none so far. Those special scenarios aren't very common, but if someone runs into one of them this feature will probably save them big time. Global variables make you go from various special scenarios with arrays being very hard to undoable unless the application provides a specific kind of filter function or processing function to create a new array from it, to easily almost Turing complete (minus infinite loops) with all sorts of special stuff being possible with workarounds if really needed in some situation. 2. Construct/assign a new array in the template from a previous one with a given filter condition If you don't like the idea, you might be able to fix the specific thing I want by allowing to create an array with a filtered condition comparable to Python's list comprehension from an existing array, and then allow the template to iterate and examine the length of the resulting new array instead. However that is both probably more complicated for me to use for my specific use case, and also a more limited solution that doesn't cover many slightly more complex scenarios which I'm sure aren't that impossible to run into. I really think adding global variables that can be set/changed with the template is a much more universally useful idea. |
It looks like
Note that the |
Nice, that seems very suitable and sorry for missing it. Is there a reason why no such function is in the generic Go Template set of functions? (something like that "where" for array filtering) I also noticed there is no easy starts-with strings check or other basic string operations like Also I would still like to point out that if another application is not as careful with supplying additional helper functions, generic global scope variables could still help people a lot in some scenarios.. |
It has simply never been proposed before. Perhaps we should take a look at the primitives provided by
Indeed, but for the reasons I described above I don't think this will happen. Sorry. That being the case, I'm going to close this issue for now. Thank you for taking the time to report the issue in such detail. Your feedback has been very helpful thus far. |
I am trying to do a very simple task in a Go Template which amounts to "if something in a range is found that fulfills a certain condition then output A else output B".
However, this is really trivial task appears to be absolutely impossible to do:
Why is it impossible? Because it appears to be not doable to pass any information from the inner loop outside again since it immediately expires in the scope, so the {{ if .. }} at the end never works as intended.
This stackoverflow answer http://stackoverflow.com/questions/28674199/in-a-go-template-range-loop-are-variables-declared-outside-the-loop-reset-on-ea describes workarounds involving modifying application code.
However, this is completely unrealistic and impractical because in the real world, usually the person writing a template is an end-user of the application and not a developer that would fork it and modify the application internals just to do such a simple task.
Therefore, please stop intentionally crippling the Go Template variable handling and allow people to write functional templates where at least some very simple logical tasks that aren't absolutely trivial can be done without immediately being required to fork and rewrite the entire application. (yes I get it, logic is always supposed to reside in the application. But sometimes that's just not a practical solution if you need a template that works right now and not in 10 years when the application was finally patched with the specific functionality required in your template.)
PS: I'm not very proficient in Go. My sincere apologies if the task above is actually possible without modifying application code. However, I read a lot of docs on Go Template by now and I haven't found a single way of doing it that doesn't require me to patch the host application..
The text was updated successfully, but these errors were encountered: