我有一个单独的帮助宏文件,所以我在需要时导入一个。这是有问题的宏:
{% 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 %}
Run Code Online (Sandbox Code Playgroud)
似乎它返回 dict,但事实并非如此。它返回“markupsafe.Markup 对象”,它导致:
UndefinedError: 'markupsafe.Markup object' has no attribute 'itervalues'
Run Code Online (Sandbox Code Playgroud)
等等。如何强制 Jinja 在不转换的情况下返回 dict?
我通过返回一个字符串并将其解析回字典来克服了 Ansible 中的类似问题(它有一个内置的过滤器from_json) :json
{% macro get_dict() -%}
{%- set d = dict() -%}
{{- d.update(foo="bar") -}}
{{- d.update(spam="eggs") -}}
{{- d|to_json -}}
{%- endmacro %}
{% set d = get_dict()|from_json %}
{% for key, value in d.items() %}
{{- key }}: {{ value }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
如果不使用 Ansible,可以轻松定义from_json过滤器,如下所示(其中env是 的实例jinja2.Environment):
def from_json(val):
return json.loads(val)
env.filters["from_json"] = from_json
Run Code Online (Sandbox Code Playgroud)
不,宏只能返回模板片段(以Markup对象的形式),而不是像字典这样的 Python 对象。改为使用 Python 代码;向传递给模板的项目添加函数或添加模板全局。
在您的情况下,您似乎正在重新实现slice()filter,因此在这种情况下甚至不需要这样做。