jinja2:宏选择宏或动态宏调用 [英] jinja2: macro selecting macro or dynamic macro calls
问题描述
我有一个正在处理的命名元组列表,每个命名元组在渲染要求上略有不同,因此我想基于属性调用适当的宏.我有这个:
I have a list of namedtuples I'm going through, each slightly differing in rendering requirements, so I want to call the proper macro based on an attribute. What I have is this:
{% macro format_item(item) %}
{% if item.type_of == 'a' %}
{{ format_a(item) }}
{% elif item.type_of == 'b' %}
{{ format_b(item) }}
{% elif item.type_of == 'c'%}
{{ format_c(item) }}
{% elif item.type_of == 'd'%}
{{ format_d(item) }}
{% else %}
{{ format_general(item) }}
{% endif %}
{% endmacro %}
但是我想要的是这样的东西:
but what I want is to something like:
...iterating through list of items
{{ call macro based off item.type_of }}
这时,在常规python中,我会做类似
at this point in regular python I'd do something like
getattr(object_with_method_to_produce_templates, item)
,但是还没有找到有效使用attr过滤器的方法(如果我可以在这种情况下完全使用它的话).
but haven't figured out a way to use the attr filter effectively (if I can use it properly in this situation at all).
我发现flask.get_template_attribute在其他地方看起来可能很有趣(如果可以的话,我可以提前做所有事情并将预计算和预格式化的项目发送到模板).可能太多了,超出了我当前要执行的操作.
I've found flask.get_template_attribute looking elsewhere which might be interesting (if I can instead just do it all ahead of time and send a precalculated and preformatted item to the template). Maybe too much and beyond what I want to do at this time.
从宏的各种列表而不是将来可能会变得相当大的if列表中调用的更好方法是什么?似乎是一个常见问题,但我没有迷失在寻找确切的答案.
What is a better way to call from a varied listing of macros instead of a list of if then's that might get rather large in the future? Seems like a common question, but I have not stumbled on the exact answer I'm looking for.
我将此添加到了我正在做的事情中,试图生成一个可调用的宏作为要渲染的项目的一部分
I added this to what I was doing, trying to generate a callable macro as part of the item I want to render
from flask import get_template_attribute
from jinja2 import Template
test_template = Template('{% macro test_macro(item) %}<div id="test-div">sent to me: {{ item }}</div>{% endmacro %}')
...在项目生成中...
...in item generation...
template = get_template_attribute(test_template, 'test_macro')
...在模板中...然后为每个项目重复项
...in template...iterate items then for each item
{{ item.template("testing this method") }}
这是一种工作方式,但只会产生一个字母一个字母的字符串,而不是像常规宏那样生成(即,div不会呈现为div,而只会呈现为文本).
which sort of works but only generates the string letter for letter, not as a regular macro would(i.e. the divs aren't rendered as divs, only as text).
<div id="test-div">sent to me: testing this method</div>
因此,我需要为Template提供一些背景信息,或者一些与目标内容更接近但看起来不正确的东西.
So I need to give Template some context, or something this is closer to what was aiming for but doesn't seem right.
{{ item.template("testing this method")|safe }}
返回我一直在寻找的东西,所以这是可以通过的,我也许可以绕过我所拥有的namedtuple安排,而只是通过一个带有...的宏来实现.这是最佳/可取还是一团糟?
returns what I was looking for, so this is passable, I might be able to bypass the namedtuple arrangement I had and just pass a macro with...more working on it I suppose. Is this optimal/preferable or a mess though?
推荐答案
您可以创建一个Jinja2过滤器,该过滤器从当前上下文中获取Macro,然后对Macro求值.过滤器为:
You can create a Jinja2 filter which gets the Macro from the current context and then evaluates the Macro. The filter is:
@contextfilter
def call_macro_by_name(context, macro_name, *args, **kwargs):
return context.vars[macro_name](*args, **kwargs)
在此处查看完整答案.
这篇关于jinja2:宏选择宏或动态宏调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!