Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jinja2 nested loop counter

Tags:

flask

jinja2

{% set cnt = 0 %}
{% for room in rooms %}
  {% for bed in room %}
    {% set cnt = cnt + 1 %}
  {% endfor %}
{{ cnt }}
{% endfor %}

Say we have that nested loop, printed cnt will ALWAYS be 0, because that's what it was defined when we entered the 1st for loop. When we increment the counter in the inner loop, it seems to only be a local variable for the inner loop -- so it will increment while inside the loop, but then that local cnt is gone. HOW can we modify the global cnt???

As great as the Jinja2 doc may be, they are unclear about set variable scopes. The only thing mentioning scope was the "scoped" modifier for inner blocks, but I guess it can't be applied to everything ... crazy.

like image 542
veryxcit Avatar asked Sep 12 '13 03:09

veryxcit


2 Answers

Scoping rules prevent you from accessing a variable declared outside a loop from inside the loop

To quote Peter Hollingsworth from his previous answer,

You can defeat this behavior by using an object rather than a scalar for 'cnt':

{% set cnt = [0] %}
{% for room in rooms %}
  {% for bed in room %}
    {% if cnt.append(cnt.pop() + 1) %}{% endif %} 
  {% endfor %}
{{ cnt[0] }}
{% endfor %}
total times through = {{ cnt[0] }}
like image 101
Chris Warth Avatar answered Oct 13 '22 08:10

Chris Warth


For each loop, there is a loop object generated which have an index attribute.

http://jinja.pocoo.org/docs/dev/templates/#for

To access parent loop index, you can do like this: http://jinja.pocoo.org/docs/dev/tricks/#accessing-the-parent-loop

Or you could use enumerate which work the same in Jinja as in Python https://docs.python.org/2/library/functions.html#enumerate

like image 32
Pyglouthon Avatar answered Oct 13 '22 08:10

Pyglouthon