Jinja2 Namespaces and Variable Scope

I have been doing some Network automation lately, specifically using the Juniper vSRX and generating config templates via Ansible.

I quickly found out about variable scope in Jinja.

Please keep in mind that it is not possible to set variables inside a block and have them show up outside of it. This also applies to loops. The only exception to that rule are if statements which do not introduce a scope. - Jinja Docs

Putting a lot of logic into templates is probably not a good idea, but I’m doing it anyway in this case. :)

Example. I have two friends. One has a car, one doesn’t. Does the group of friends have a car?


#!/usr/bin/env python

from jinja2 import Template

friends = []

friend1 = {
    "name": "Frank",
    "car": False
}
friend2 = {
    "name": "Anna",
    "car": True
}

friends.append(friend1)
friends.append(friend2)

t_example = """
{% set ns = namespace(hasCar=false) %}
{% for f in friends %}
Friend {{ f.name }}
{% if f.car == true %}
{% set ns.hasCar = true %}
{% endif %}
{% endfor %} {# for n in friends #}

{% if ns.hasCar == true %}
SOMEONE HAS A CAR: TRUE
{% else %}
SOMEONE HAS A CAR: FALSE
{% endif %}

"""

template = Template(t_example, trim_blocks=True)

render = template.render(friends=friends)

print render

If I run this in ipython I get:


In [1]: run jinja-ns.py

Friend Frank
Friend Anna

SOMEONE HAS A CAR: TRUE


In [2]:

That’s it. Namespaces in jinja.