2012-12-24 38 views
7

我有一个namedtuples列表,我正在经历,每个渲染要求略有不同,所以我想根据属性调用适当的宏。我所拥有的是这样的:jinja2:宏选择宏或动态宏调用

{% 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 %} 

但我想是这样的:

...iterating through list of items 
{{ call macro based off item.type_of }} 

在这一点上在常规的Python我会做这样的事情

getattr(object_with_method_to_produce_templates, item) 

但避风港没有想出一种有效使用attr过滤器的方法(如果我能在这种情况下正确使用它)。

我发现flask.get_template_attribute在其他地方看起来可能很有趣(如果我可以提前做所有事情,并将预先计算并预先格式化的项目发送到模板)。可能太多了,超出了我现在想要做的。

什么是更好的方式来从各种各样的宏列表中调用,而不是如果那样的列表在将来会变得相当大?看起来像一个常见的问题,但我没有偶然找到我正在寻找的确切答案。

编辑:

我说这我在做什么,想产生一个可调用宏作为该项目的一部分,我想渲染

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 %}') 

...项代...

template = get_template_attribute(test_template, 'test_macro') 

...模板...迭代的项目,然后对每个项目

{{ item.template("testing this method") }} 

哪种类型的作品只能生成字母的字符串,而不是常规的宏(即, div不会呈现为div,只能作为文本呈现)。

<div id="test-div">sent to me: testing this method</div> 

所以我需要给模板一些背景,或者说这是更接近什么瞄准,但看起来不正确。

EDIT2:

{{ item.template("testing this method")|safe }} 

回报什么,我一直在寻找的,所以这是差强人意,我也许能绕过namedtuple安排我和刚刚通过宏...更多的工作就可以了我假设。这是最佳/优选还是一团糟?

+0

查看Jinja文档中的HTML转义和安全过滤器。 – voscausa

+0

好吧,我已经看过他们,但没有做出我需要做的确切连接。我想我所做的是创建一个宏作为一段代码,但没有将其标记为html(如文​​件扩展名所示),所以宏只是以纯文本的形式被重新绑定,嗯,让我们来讨论一下。 – blueblank

回答

5

您可以创建一个Jinja2过滤器,从当前上下文获取宏,然后评估宏。该过滤器是:

@contextfilter 
def call_macro_by_name(context, macro_name, *args, **kwargs): 
    return context.vars[macro_name](*args, **kwargs) 

查看完整的答案here