nunjucks: Block scoping is too strict (stricter than Jinja) in 3.0.0.
There were a number of commits included in 3.0.0 that fixed scoping issues, but now it seems that {% call %}
blocks no longer have access to variables set in their parent scope. This differs from the Jinja2 implementation.
In Jinja2, the following code:
{% macro inside() %}
<div>inside: {{ caller() }}</div>
{% endmacro %}
{% macro outside(var) %}
<div>outside: {{ var }}</div>
{% call inside() %}
{{ var }}
{% endcall %}
{% endmacro %}
{{ outside('foobar') }}
Outputs:
<div>outside: foobar</div>
<div>inside: foobar</div>
In Nunjucks 3.0.0, the output is:
<div>outside: foobar</div>
<div>inside: </div>
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 3
- Comments: 25 (4 by maintainers)
Commits related to this issue
- Downgrade nunjucks (https://github.com/mozilla/nunjucks/issues/906). — committed to oddbird/sassdoc-theme-herman by jgerigmeyer 8 years ago
- Improved previews (#23) * Previews are mostly self-styling * Oops * add split filter and use it to collate font weight and style * Font weights and styles are automated in previews * Star... — committed to oddbird/sassdoc-theme-herman by mirisuzanne 8 years ago
- Improve broken tests for https://github.com/mozilla/nunjucks/issues/906 — committed to oddbird/nunjucks by jgerigmeyer 7 years ago
- First (unsuccessful) attempt at fixing https://github.com/mozilla/nunjucks/issues/906 — committed to oddbird/nunjucks by jgerigmeyer 7 years ago
- Allow {% call %} blocks to access parent scope. Fixes #906 — committed to mozilla/nunjucks by fdintino 7 years ago
- keep nunjucks to v2 for now, see https://github.com/mozilla/nunjucks/issues/906 — committed to alphagov/govuk-prototype-kit by joelanman 7 years ago
- Merge pull request #994 from mozilla/fix-call-scope Allow {% call %} blocks to access parent scope. Fixes #906 — committed to mozilla/nunjucks by fdintino 7 years ago
I have a fix for this. I’ll clean it up later today and push it out.
What threw me (and I’m guessing others as well) is that there are tests that test for the wrong behavior for
{% set %}
, and so fixing this bug was causing those tests to “fail.” I verified the correct behavior with jinja2 and amended those tests.I’ll try to take a look at this issue over the next weekend.
It’s a common misconception that Jinja2 follows the conventions of Python everywhere, but that’s not generally true. It supports a subset of python syntax, but template-specific constructs like blocks, macros, includes, template scoping, and the
set
andcall
tags don’t have obvious analogous in Python. The Jinja2 docs are pretty explicit in stating that writes with{% set %}
should not modify variables in the outer scope (with the exception of if/else tags): see the Jinja2 docs on assignments, specifically the second section titled “Scoping Behavior.” It’s definitely intentional. Since nunjucks lacks a consistent specification for how scope should act (and not unrelatedly there are a lot of bugs with scope) my preference would be to defer to Jinja’s behavior generally.I will note that Twig does not isolate writes inside
{% for %}
blocks, so I’m open to making those an exception the same way{% if %}
and{% else %}
tags are. As long as the behavior is well considered.