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

Jinja2 2.9.4 - {% set %} and {% include %} don't work in the same template. #659

Closed
andymcc opened this issue Jan 12, 2017 · 7 comments
Closed

Comments

@andymcc
Copy link

andymcc commented Jan 12, 2017

Expected Behavior

When a template contains:

{% set myvar = "foo" %}
{{ myvar }}
{% include "include.j2" %}

And the include.j2 template contains anything, for example:

bar

The original template should render:

foo
bar

Actual Behavior

In 2.8 this works normally.

In 2.9.3 & 2.9.4 the template doesn't render at all and drops an error:

KeyError: 'undefined variable: 0'

However, it will render with the {% set %} line templated when no {% include %} line exists, e.g.:

{% set myvar = "foo" %}
{{ myvar }}

Or with the {% include %} line without the {% set %} line, e.g.:

{% include "include.j2" %}

Template Code

root@jinja2fix# cat templates/setincl.j2
{% set myvar = "foo" %}
{{ myvar }}
{% include "include.j2" %}

root@jinja2fix# cat templates/include.j2
bar

Actual Run

I'm using Ansible 2.2.0 (I'll file a bug with Ansible too as I know this may not be considered a Jinja2 bug) - it's easily repeatable with the ad-hoc ansible command though:

root@jinja2fix:/opt/test_jinja# ansible localhost -m template -a "src=setincl.j2 dest=/tmp/test.file"

localhost | FAILED! => {
    "changed": false,
    "failed": true,
    "msg": "KeyError: 'undefined variable: 0'"
}

Here is a more "complete" run to show the failure and success (in 2.8). Additionally, it shows that it will render properly with either just the {% set %} line, or just the {% include %} line - but not both.

https://gist.github.com/andymcc/2ddf98b50fa07e3f8b8648a440499fb8

I've added to a bug in Ansible, that already exists and seems related: ansible/ansible#20063

Your Environment

  • Python version: 2.7.12
  • Jinja version: 2.9.3 & 2.9.4 (tested on both)
@mitsuhiko
Copy link
Contributor

I cannot reproduce this at all in Jinja2. Added this regression test in 3e9937c but it passes.

@mitsuhiko
Copy link
Contributor

There must be more to this story. I'm going to close this bug however I will monitor the mentioned issue over here: ansible/ansible#20063

@ghost
Copy link

ghost commented Jan 28, 2017

I have the same bug.

<div id="owl{{ carousel_count }}" class="owl-carousel owl-theme">
    {% set owl_count=0 %}
    {% set owl_all = channels | length %}
    {% for owl_channel in channels %}

        {% set owl_count=owl_count+1 %}

        {% if owl_all<14 or owl_count % 2 != 0 %}
            <div class="item">
        {% endif %}

    <div class="ps-bl">
        <img src="{{ owl_channel.image }}" style="cursor: pointer;"
             onclick="goChannel('{{ owl_channel.url }}')"/>
        <div class="tit-chanel" style="cursor: pointer;">{{ owl_channel.name }}</div>
        <div class="flg j1 ato-flag"><img src="{{ owl_channel.flag }}" alt=""></div>
        <a class="love" href="#" data-id="{{ owl_channel.id }}"></a>
    </div>

    {% if owl_all < 14 or owl_count %2 == 0 or owl_count == owl_all %}
        </div>
        <!-- .item-->
    {% endif %}

    {% endfor %}

</div>

The problem with owl_count. It always equals 1.
With Jinja2 2.8 it works fine.

@ThiefMaster
Copy link
Member

This looks a lot like something that could be done much cleaner with the batch filter. Also, check out the various attributes exposed on the loop object.

@mitsuhiko
Copy link
Contributor

Variables cannot be set in loops and that is intentional. It was never documented that you can override variables from higher scopes and that was considered a bug. See also #641

@ThiefMaster
Copy link
Member

Maybe it'd be worth raising an exception when trying to do this in a way that worked in 2.8 but breaks in 2.9 to make it very clear that something is going wrong (except for weird behavior one might not notice immediately)?

drybjed added a commit to drybjed/debops that referenced this issue Mar 14, 2018
This patch fixes the bug with backwards-incompatible change in Jinja2 >=
2.9.4 which breaks use of the 'import' keyword in loops. More details:

    pallets/jinja#659

In this case, the 'normalize.css' file cannot be directly included in
the 'index.html' welcome page, therefore it will be copied alongside it
instead.
@VladUsatii

This comment has been minimized.

@pallets pallets locked as resolved and limited conversation to collaborators Aug 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants