2012-12-24 36 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