JJIA2:在模板内呈现模板 [英] Jinja2: render template inside template

查看:31
本文介绍了JJIA2:在模板内呈现模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在字符串提供的另一个模板内呈现JJIA2模板?例如,我想要字符串

{{ s1 }}

要呈现给

Hello world

给定以下词典作为Template.render的参数:

{ 's1': 'Hello {{ s2 }}', 's2': 'world' }

我知道可以使用include标记将s1的内容分隔到另一个文件,但这里我不想遵循这种方式。

推荐答案

我没有轻松测试这些想法的环境,但我正在探索Airflow使用JJJA模板的类似情况。

根据我所能找到的最佳方法是显式地在外部模板中呈现内部模板字符串。为此,您可能需要传递或导入参数词典中的the Template constructor

以下是一些(未经测试的)代码:

from jinja2 import Template
template_string = '{{ Template(s1).render(s2=s2) }}'
outer_template = Template(template_string)
outer_template.render( 
    s1='Hello {{ s2 }}', 
    s2='world',
    Template=Template
)

这远不如您希望的那样干净,因此我们或许可以通过创建custom filter来进一步改进,这样我们就可以这样使用它:

{{ s1|inner_render({"s2":s2}) }}

这里有一个自定义的过滤,我认为可以完成这项工作:

from jinja2 import Template
def inner_render(value, context):
    return Template(value).render(context)

现在,让我们假设我们想要与外部模板相同的上下文,并且-不管怎么样-让我们呈现任意深度的级别N。希望一些示例用法如下所示:

{{ s1|recursive_render }}

{{ s3|recursive_render(2) }}

从我们的自定义过滤获取上下文的一种简单方法是使用contextfilter decorator

from jinja2 import Template
from jinja2 import contextfilter
@contextfilter
def recursive_render(context, value, N=1):
    if N == 1:
        val_to_render = value
    else:
        val_to_render = recursive_render(context, value, N-1)
    return Template(value).render(context)
现在您可以执行类似s3 = '{{ s1 }}!!!'{{ s3|recursive_render(2) }}应该呈现为Hello world!!!的操作。我想您可以更深入地通过计数括号来检测要呈现的级别数。


看过所有这些之后,我想明确指出这非常令人困惑

虽然我确实认为我发现在我非常具体的气流使用中需要2个级别的渲染,但我无法想象还有比这更多的级别需要。

如果您正在阅读"这正是我需要的"的想法:无论您尝试做什么,都可能更有说服力。后退一步,考虑到您可能有xy problem,并重新阅读JJJA的文档,以确保没有更好的方法。

这篇关于JJIA2:在模板内呈现模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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