jinja2:宏选择宏或动态宏调用 [英] jinja2: macro selecting macro or dynamic macro calls

查看:124
本文介绍了jinja2:宏选择宏或动态宏调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个正在处理的命名元组列表,每个命名元组在渲染要求上略有不同,因此我想基于属性调用适当的宏.我有这个:

I have a list of namedtuples I'm going through, each slightly differing in rendering requirements, so I want to call the proper macro based on an attribute. What I have is this:

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

但是我想要的是这样的东西:

but what I want is to something like:

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

这时,在常规python中,我会做类似

at this point in regular python I'd do something like

getattr(object_with_method_to_produce_templates, item)

,但是还没有找到有效使用attr过滤器的方法(如果我可以在这种情况下完全使用它的话).

but haven't figured out a way to use the attr filter effectively (if I can use it properly in this situation at all).

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

I've found flask.get_template_attribute looking elsewhere which might be interesting (if I can instead just do it all ahead of time and send a precalculated and preformatted item to the template). Maybe too much and beyond what I want to do at this time.

从宏的各种列表而不是将来可能会变得相当大的if列表中调用的更好方法是什么?似乎是一个常见问题,但我没有迷失在寻找确切的答案.

What is a better way to call from a varied listing of macros instead of a list of if then's that might get rather large in the future? Seems like a common question, but I have not stumbled on the exact answer I'm looking for.

我将此添加到了我正在做的事情中,试图生成一个可调用的宏作为要渲染的项目的一部分

I added this to what I was doing, trying to generate a callable macro as part of the item I want to render

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

...在项目生成中...

...in item generation...

 template = get_template_attribute(test_template, 'test_macro')

...在模板中...然后为每个项目重复项

...in template...iterate items then for each item

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

这是一种工作方式,但只会产生一个字母一个字母的字符串,而不是像常规宏那样生成(即,div不会呈现为div,而只会呈现为文本).

which sort of works but only generates the string letter for letter, not as a regular macro would(i.e. the divs aren't rendered as divs, only as text).

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

因此,我需要为Template提供一些背景信息,或者一些与目标内容更接近但看起来不正确的东西.

So I need to give Template some context, or something this is closer to what was aiming for but doesn't seem right.

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

返回我一直在寻找的东西,所以这是可以通过的,我也许可以绕过我所拥有的namedtuple安排,而只是通过一个带有...的宏来实现.这是最佳/可取还是一团糟?

returns what I was looking for, so this is passable, I might be able to bypass the namedtuple arrangement I had and just pass a macro with...more working on it I suppose. Is this optimal/preferable or a mess though?

推荐答案

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

此处查看完整答案.

这篇关于jinja2:宏选择宏或动态宏调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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