-
Notifications
You must be signed in to change notification settings - Fork 170
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
Handle deferred modification of an outer scoped variable inside a call tag #1144
Conversation
I have been looking at partial rendering simplifications. When I looked at this example, I wonder if we can produce the partially rendered result like this
I tried to modify a few lines of the code, and was able to produce that. However, what would be the unexpected consequence of this simplification? This piece of code in isolation should be safe, but it may not be applicable in complex nested situations. I just throw some thoughts on this. |
@hs-lsong I like the exploration of alternative options here, and implementing something like you suggested would be possible. The eager execution output would look simpler in cases where the list is just output to a string, but in most other cases it would unfortunately not look simpler (the first phase output would look about the same) and it would be more difficult to construct. It would require extra context about what the operations do. For the For example, the If we can make the changes to fully resolve EL expressions containing deferred values, we would end up with a more difficult list that we'd need to reconstruct if some jinjava code attempts to access the deferred value. We'd need to store in the list a reference to what the deferred value is when we want to access it:
If we just stored that as Another problem we would run into would be that, for functions, filters, etc that take in There are more hurdles that we'd have to work through if we wanted to go with such a solution. It would be possible to do, but even if we did solve all hurdles, I don't it as being worth the effort as we'd still be handling the resolving and reconstructing of the What I've found to be the simplest solution to these problems of how to treat a |
Thanks for the new example and explanation. Since that new example is just a macro, after rendering it would be empty. I add some caller, and found that would still produce simple, more readable output.
I defined a list, and call the macro. If the
If the
or, if the input is deferred
|
What are you storing in the |
A
{% call %}
tag has some tricky scoping.It functions by creating a child scope and putting temporary macro function
caller()
on that scope. When the macro function evaluates, it will also create a child scope. Part of eager execution's logic is to make sure that we don't reconstruct a variable on the wrong scope. So it won't reconstruct a variable on an inner scope if it was originally declared on an outer scope.What this means is that we must ask it to reconstruct the macro function and the modified variable separately, since they both need to be deferred as a result of the call tag, but exist on different scopes since the call tag creates multiple scopes:
So we must call
getPrefixToPreserveState()
when on level 2 and level 1.