pythonjinja2

Return a dict object from Jinja2 macros


I have a separate file for helper macros, so I import one when needed. Here is problematic macro:

{% macro row_cycler(tiles) -%}
    {%- set row1 = [] -%}
    {%- set row2 = [] -%}
    {%- set row3 = [] -%}
    {%- set row4 = [] -%}
    {%- set rows = cycler(row1, row2, row3, row4) -%}
    {% for column in tiles|batch(4) -%}
        {% for tile in column -%}
            {%- do rows.next().append(tile) -%}
        {%- endfor %}
    {%- endfor %}
    {{ dict(row1=row1, row2=row2, row3=row3, row4=row4) }}
{%- endmacro %}

Seems it returns dict, but it's not. It returns "markupsafe.Markup object", it leads to something that:

UndefinedError: 'markupsafe.Markup object' has no attribute 'itervalues'

and so on. How can I force Jinja to return dict without converting?


Solution

  • No, macros can only return template snippets (in the form of Markup objects), not Python objects like dictionaries. Use Python code for that instead; add a function to the items passed into the template or add a template global.

    In your case it looks as if you are re-implementing the slice() filter, so perhaps that's not even needed in this case.