Andrew Cassidy
Andrew Cassidy

Reputation: 2998

Access parent for loop scope in child template in Jinja2

parent.txt

{% for dict in list_of_dictionaries %}
    {% block pick_dictionary_element %}
    {% endblock %}
{% endfor %}

child_one.txt

{% extends "parent.txt" %}
{% block pick_dictionary_element %}
    {{ dict.a }}
{% endblock %}

child_two.txt

{% extends "parent.txt" %}
{% block pick_dictionary_element %}
    {{ dict.b }}
{% endblock %}

Then:

from jinja2 import Template, Environment, FileSystemLoader
e = Environment(loader=FileSystemLoader("./"))
e.get_template("child_one.txt").render(list_of_dictionaries=[{'a': 'a', 'b': 'b'}])

produces an empty output. How can I access the dict var from the parent for loop? I kind of imagined jinja just in-lining the pick_dictionary_element and the child having the for loop scope of its parent?

Upvotes: 5

Views: 1690

Answers (2)

Stephen Rauch
Stephen Rauch

Reputation: 49832

The key to what you are trying to do is to use the scoped keyword on your block:

{# parent.txt #}
{% for dict in list_of_dictionaries %}
    {% block pick_dictionary_element scoped %}
    {% endblock %}
{% endfor %}

Why was this hard to debug?

You made the mistake of using the name dict in the loop:

{% for dict in list_of_dictionaries %}

The side effect of this was that the child template did not readily complain, since the symbol dict exists in its context. If instead, you had done something like:

{# parent.txt #}
{% for a_dict in list_of_dictionaries %}
    {% block pick_dictionary_element %}
    {% endblock %}
{% endfor %}

{# child_one.txt #}
{% extends "parent.txt" %}
{% block pick_dictionary_element %}
    {{ a_dict.a }}
{% endblock %}

You would have been told:

jinja2.exceptions.UndefinedError: 'a_dict' is undefined

Upvotes: 3

shaun shia
shaun shia

Reputation: 1172

Starting with Jinja 2.2, you can explicitly specify that variables are available in a block by setting the block to “scoped” by adding the scoped modifier to a block declaration

http://jinja.pocoo.org/docs/2.9/templates/#block-nesting-and-scope

{# parent.txt #}
{% for dict in list_of_dictionaries %}
    {% block pick_dictionary_element scoped %}
    {% endblock %}
{% endfor %}

Upvotes: 1

Related Questions