-
Notifications
You must be signed in to change notification settings - Fork 172
Add a new execution mode that preserves any undefined variable #1273
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
Open
hs-lsong
wants to merge
10
commits into
master
Choose a base branch
from
preserve-undefined-execution-mode
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…ss rendering
Introduces a new execution mode that preserves unknown/undefined variables
as their original template syntax instead of rendering them as empty strings.
This enables multi-pass rendering scenarios where templates are processed
in stages with different variable contexts available at each stage.
Key behaviors:
- Undefined expressions preserved: {{ unknown }} → {{ unknown }}
- Defined expressions evaluated: {{ name }} with {name: "World"} → World
- Control structures (if/for) with undefined conditions preserved
- Variables explicitly set to null are also preserved
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace contains() assertions with isEqualTo() to make test expectations explicit and show the exact preserved output format. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of relying solely on eager mode's internal representations,
use a hybrid approach:
- Extend EagerExecutionMode to preserve control structures (if/for/set tags)
- Add PreserveUndefinedExpressionStrategy to preserve original expression
syntax like {{ name | upper }} instead of {{ filter:upper.filter(...) }}
This gives the best of both worlds: tags with undefined variables are
preserved, and expressions maintain their readable original format.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable deferred execution mode to ensure set tags are preserved even
when the RHS is fully resolved. This is needed for multi-pass rendering
where variables need to remain defined in subsequent render passes.
Example: {% set x = name %} with {name: "World"}
Before: World (x would be undefined in next pass)
After: {% set x = 'World' %}World (x remains defined)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ervation
Add a new context configuration flag that allows set tags with fully
resolved RHS values to be preserved in output, independent of macro
deferral behavior. This enables both:
- Macros to partially evaluate (preserving only undefined vars within)
- Set tags to be preserved as {% set x = 'value' %} for multi-pass rendering
Also adds import/from macro tests to verify partial macro evaluation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Document the new execution mode including: - Use case and purpose - Usage examples - Behavior tables for expressions, control structures, set tags, macros - Multi-pass rendering example - Implementation details and new context flags 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Multi-pass rendering scenarios may need to preserve Jinjava comment tags
({# comment #}) for later processing stages. This adds a context flag
that, when enabled, outputs comments as-is instead of stripping them.
PreserveUndefinedExecutionMode now enables this flag by default.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The static instance() method intentionally hides the parent class method to return the correct singleton for this execution mode, matching the pattern used in NonRevertingEagerExecutionMode. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When extends tag path is undefined in PreserveUndefinedExecutionMode, block tags were being processed normally causing their content to be extracted without the block wrapper. This fix adds an isExtendsDeferred flag that gets set when ExtendsTag throws DeferredValueException, allowing BlockTag to also defer and preserve its original syntax. This enables proper multi-pass rendering where templates with undefined extends paths preserve both the extends and block tags for later resolution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Verifies that when a grandchild template extends a child template (resolved path), and the child extends a parent (undefined path), the child's extends and block tags are correctly preserved. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
A new execution mode for Jinjava that preserves unknown/undefined variables as their original template syntax instead of rendering them as empty strings. This enables multi-pass rendering scenarios where templates are processed in stages with different variable contexts available at each stage.
See preserve-undefined-execution-mode.md for details.