user3258819
user3258819

Reputation: 251

Jinja variable scope or how can I access integer which have been incremented inside loop?

I have the following JINJA template:

{% set counter = 0 %}
{% for f in somearray %}
{% set counter = counter + 123 %}
{% endfor %}

// here I want to print {{counter}}, but it is always 0.

I looked at this answer Can a Jinja variable's scope extend beyond in an inner block? but it did not help. I tried to create array variable and access it

{% set counter = 0 %}
{% set sz = [0] %}
{% for f in somearray %}
{% set counter = counter + 123 %}
{% set sz[0] = counter %} <---- CRASH HERE
{% endfor %}

JINJA documentation says nothing about array access... Please help.

Upvotes: 2

Views: 2275

Answers (1)

Alvaro Fuentes
Alvaro Fuentes

Reputation: 17455

To use an array as a counter you need to modify your code (and do some hacks!) I will show you the way of doing what you want without extensions.

Ok, the main problem in your code is that when you set a variable on a jinja statement it keeps its value just in that scope (is like a local variable definition on a function in python) and since jinja doesn't provide a strightforward way of setting outside variables created on the template you need to do some hacks. This magic works using a list:

import jinja2

env = jinja2.Environment()
print env.from_string("""
{%- set counter = [0] -%}
{%- for f in somearray -%}
{%- set _ = counter.append(counter.pop()+1) -%}
{%- endfor -%}
{{counter[0]}}
""").render(somearray=[1,2,3,4])

Steps:

  1. Create a list with the value of your counter.
  2. Use set _ = ... to perform some action that will have no effect on your template (just setting the varibale _ to None which is almost nothing in your context at least you decide you need a variable called _).
  3. Use the combination append/pop to change the value of the counter (this works in jinja since it allows calling functions on variables on a set statement)
  4. Use the value in the list whenever you need the value of the counter.

And if you wonder what is the output of previous code here it comes:

4

Hope it helps.

Upvotes: 2

Related Questions