Skip to content
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

Inconsistent scoping behavior in "macro", "include" and template inheritance. #561

Closed
legutierr opened this issue Oct 24, 2015 · 6 comments
Labels

Comments

@legutierr
Copy link

This template...

{% macro setval() %}{% set val = 22 %}{% endmacro %}{{ setval() }}{{ val }}

...evaluates to "" (i.e., the empty string). The value set inside the macro doesn't leak out of the the local macro scope. However, this template...

{% macro setval() %}{% set val = 22 %}{% endmacro %}{% set val = 44 %}{{ setval() }}{{ val }}

...evaluates to "22". The value set inside the macro leaks out of the macro scope. In Jinja, these two templates evaluate to "" and "44", respectively.

@legutierr
Copy link
Author

There's a similar weirdness happening with the include tag as well. Given this simple template...

{# template.html #}
{% set var = 22 %}

...you get two very different results when you include it. First...

{% include "template.html" %}{{ var }}

...evaluates to "" (the empty string). The value of var does not leak out of the included template's scope. This template, however, does leak its scope...

{% set var = 44 %}{% include "template.html" %}{{ var }}

...evaluating to "22". In Jinja, these two templates evaluate to "" and "44", respectively, as before.

@legutierr legutierr changed the title Inconsistent scoping behavior in "macro" Inconsistent scoping behavior in "macro" and "include" Oct 25, 2015
@carljm
Copy link
Contributor

carljm commented Oct 26, 2015

Thanks for tracking this down! This is definitely something that should ideally be fixed, though without diving into the details I have no idea how invasive the fix will be. It's something I'd enjoy looking into if I find some time, but not sure when that will be - pull requests definitely welcome! (Even just a PR with failing tests for these issues would be a really good start.)

@legutierr
Copy link
Author

I discovered more of the same weirdness with template inheritance. Given this base template...

{# base.html #}
{% block k %}{% set var = 'parent' %}{% endblock %}

...when you execute the following template...

{% extends “base.html” %}{% block k %}{% set var = 'child' %}{{ super() }}{{ var }}{% endblock %}

...you get the expected result: ‘child’. This is the same value that Jinja emits. However, when you execute the following template...

{% extends “base.html” %}{% block k %}{{ super() }}{{ var }}{% endblock %}

...you get ‘parent’. Again, the problem is a leaking scope (in this case, that of “super()”), but only when the value is set. With Jinja, in this second case, you get ‘’ (i.e. the empty string).

And there is also a fourth inconsistency. Given this base template...

{# base2.html #}
{% set val = 'parent' %}{% block k %}{% set val = ‘inner’ %}{% endblock %}{{ val }}

...when you execute the following template...

{% extends “base2.html” %}{% block k %}{% set val = 'child' %}{% endblock %}

...you get ‘child’. The child block is leaking into the parent template. However, when you render the “base2.html” file directly, the block scope does not leak, and the template renders ‘parent’, as expected. In Jinja, both templates render to the string ‘parent’.

I hope that I will be able to help with this. If I have time, I will definitely work on it, but I'm not sure if I will.

@legutierr legutierr changed the title Inconsistent scoping behavior in "macro" and "include" Inconsistent scoping behavior in "macro", "include" and template inheritance. Nov 2, 2015
@carljm carljm added the bug label Dec 14, 2015
@carljm
Copy link
Contributor

carljm commented Jan 29, 2016

The macro portion of this should be fixed with the merge of #653 -- the isolate frame attribute added there might also help with fixing the rest of this, just needs someone to try it out and write a test.

@carljm
Copy link
Contributor

carljm commented Feb 5, 2016

Merge of #667 improves the macro component of the fix from #653, and also fixes the include portion.

@carljm carljm closed this as completed in 7edf66f Feb 17, 2016
@carljm
Copy link
Contributor

carljm commented Feb 17, 2016

Ok, I think that concludes the last of this bug, finally! Thanks again @legutierr for digging up these issues; please feel free to dig some more and see what you find :-)

carljm added a commit that referenced this issue Feb 17, 2016
carljm added a commit that referenced this issue Mar 14, 2016
* master: (88 commits)
  Bump versions for dev.
  Update maintenance docs.
  Revert accidental changes to mocha.js.
  Bump version to 2.4.0.
  Update changelog.
  Merge pull request #694 from mariusbuescher/master
  Update changelog.
  Add support for boolean globals
  Add note about include and blocks; update wrapping of templating docs.
  Merge pull request #688 from pra85/patch-1
  Add note about include and blocks; update wrapping of templating docs.
  Update api.md
  fixed bad character leading % in {% endraw %}
  Respect null/none as a value in its own right, distinct from undefined. Fixes #478.
  Use dot reporter for npm test.
  Don't bail on first failed test in 'npm test'.
  Add acknowledgement for #561 to changelog.
  Tighter scoping of vars in blocks, to match Jinja2. Fixes #561.
  Rename all test templates to use .j2 extension.
  Rename all test templates to use .j2 extension.
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants