我没有一个可以轻松测试这些想法的环境,但我在airflow使用jinja模板时正在探索类似的东西.
从我能找到的最好的方法是在外部模板中显式渲染内部模板字符串.为此,您可能需要在param字典中传递或导入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,并重新阅读jinja的文档,以确保没有更好的方法.