如何在Jinja2模板中间接调用宏? [英] How can I indirectly call a macro in a Jinja2 template?

查看:53
本文介绍了如何在Jinja2模板中间接调用宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试做这样的事情:

I'm trying to do something like this:

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

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

在此示例中,get_type是将返回obj_type_1obj_type_2的过滤器-即,要调用obj的宏的名称.我不想用配置输出标记obj,因为现在obj在几个模板中用作结构数据,根据上下文使用不同的标记来呈现.

In this example, get_type is a filter that would return obj_type_1 or obj_type_2 -- ie, the name of the macro to call for obj. I don't want to mark up obj with configuration output because right now obj is used in several templates as structural data, to be rendered with different markup depending on the context.

我知道这里的语法有些折磨,但是我认为这是因为Jinja模板中不可能立即实现我想做的事情.我正在尝试用模板替换某些配置生成代码中的if/elif/else废话,但该问题似乎是一个症结所在.

I know the syntax here is a bit tortured, but I think that's because what I want to do isn't immediately possible in Jinja templates. I'm trying to replace a big damn schwack of if/elif/else crap in some config generation code with templates, but this bit seems to be a sticking point.

推荐答案

您可以创建一个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)

如果您的应用程序需要,则可以在context.vars中查找宏之前,对macro_name执行字符串操作.

If your application requires, you can perform string manipulation on macro_name before looking up the Macro in context.vars.

这是一个完整的例子:

#!/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)

这篇关于如何在Jinja2模板中间接调用宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆