8

私はこのようなことをしようとしています:

{% macro obj_type_1 %}
stuff
{% endmacro %}
{% macro obj_type_2 %}
stuff
{% endmacro %}

{{ (obj|get_type)(obj) }}

この例では、 はorget_typeを返すフィルタです。つまり、 を呼び出すマクロの名前です。現在、いくつかのテンプレートで構造データとして使用され、コンテキストに応じて異なるマークアップでレンダリングされるため、構成出力でマークアップしたくありません。obj_type_1obj_type_2objobjobj

ここでの構文がややこしいのは承知していますが、それは、私がやりたいことを Jinja テンプレートですぐに実行できないためだと思います。いくつかの構成生成コードの if/elif/else がらくたの大きな問題をテンプレートに置き換えようとしていますが、このビットが問題のようです。

4

3 に答える 3

10

現在のコンテキストからマクロを取得し、マクロを評価する Jinja2 フィルターを作成できます。フィルターは次のとおりです。

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

アプリケーションで必要な場合は、context.vars でマクロを検索する前に、macro_name で文字列操作を実行できます。

完全な例を次に示します。

#!/usr/bin/env python
from jinja2 import Environment, contextfilter

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

template_string = """\
{%- macro MyMacro(item) %}MyMacro({{ item }}){% endmacro -%}
{{ MyMacro('direct') }}
{{ 'MyMacro' | macro('indirect') }}
"""

env = Environment()
env.filters['macro'] = call_macro_by_name
template = env.from_string(template_string)
print(template.render())

印刷する

MyMacro(direct)
MyMacro(indirect)
于 2014-07-03T12:12:01.967 に答える
4

マクロは import dict を使用して簡単に呼び出すことができます:

macros.html

{% macro render_foo(value) %}
HELLO {{ value }}!
{% endmacro %}

my_view.html

{% import "macros.html" as my_macros %}

{% set macro_name = 'render_' + dynamic_content %}
{{ my_macros[macro_name]('world') }}

次のようにレンダリングします。

HELLO world!
于 2016-04-12T12:54:07.220 に答える
0

個人的には get_type をディスパッチャとして使っているので、obj の型に基づいて特化したマクロを呼び出す jinja マクロとして実装した方が透過的です。これにより、呼び出し可能なマクロを返す必要がなくなり、同時に、特殊なマクロと、それらがいつどのように使用されるかを指示するロジックが統合されます。

于 2012-05-17T21:59:29.657 に答える