2012-12-24 20 views
7

私は通過する名前付きタプルのリストを持っていますが、レンダリングの要件が少し異なりますので、属性に基づいて適切なマクロを呼び出す必要があります。私が持っていることはこれです: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 %} 

しかし、私が欲しいのようなものにある:私は

getattr(object_with_method_to_produce_templates, item) 

が、避難所のような何かをしたい通常のpythonで、この時点で

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

attrフィルタを効果的に使用する方法を見つけました(私がこの状況で適切に使うことができれば)。

興味深いかもしれないフリンジを探しているflask.get_template_attributeがあります(代わりにすべての作業を事前に行い、あらかじめ計算してフォーマット済みのアイテムをテンプレートに送信することができます)。おそらく、あまりにも多く、私が今のやりたいことを超えている。

将来的にかなり大きくなる可能性があるかどうかのリストではなく、さまざまなマクロのリストから呼び出す方が良いでしょうか?よくある質問のようですが、私が探している正確な答えを見つけたわけではありません。

EDIT:

私はアイテムの生成に...

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を参照してください。

関連する問題