我有兴趣在多个步骤中渲染模板或在Jinja2中保留未定义变量的标记。我相信这不仅意味着创建'UndefinedSilent'类(因此模板不会因丢失的数据而崩溃),而且如果标签丢失,也会保留标签的相应变量名。
实施例: 假设我们在上下文中包含 name =“Test”,但缺少数量。
Givent以下模板:
<p>{{name}} has {{quantity}}</p>
渲染后,我需要模板成为:
<p>test has {{quantity}}</p>
有谁知道这是否可以实现?
感谢。
答案 0 :(得分:2)
在环境中为指定的参数undefined提供DebugUndefined,显然可以解决问题。呈现的模板保留{{
from jinja2 import Environment, BaseLoader,DebugUndefined
rtemplate =Environment(loader=BaseLoader,undefined=DebugUndefined).from_string("{{ a }} is defined, but {{ b}} is undefined")
print(rtemplate.render({"a":"a"}))
#The result is:
a is defined, but {{ b }} is undefined
答案 1 :(得分:1)
我也讨厌同样的行为。库 jinja2schema 提供了模板所需的变量架构。
我的解决方案的步骤是:
from jinja2 import Template
import jinja2schema
def assign(schema, data, root=''):
'''Returns a corrected data with untouched missing fields
'''
out = {}
for key in schema.keys():
if isinstance(schema[key], (str, jinja2schema.model.Scalar)):
try:
out[key] = data[key]
except:
out[key] = f'{{{{ {root+key} }}}}'
elif isinstance(schema[key], (dict, jinja2schema.model.Dictionary)):
out[key]={}
try:
data[key]
except:
data[key] = {}
out[key] = assign(schema[key], data[key], root+key+'.')
return out
# original template
template_str = '<p>{{name}} has {{quantity}}</p>'
# read schema
schema = jinja2schema.infer(template_str)
# available data
data = {'name':'test'}
# data autocompleted
data_corrected = assign(schema, data)
# render
template = Template(template_str)
print(template.render(data_corrected))
输出是
<p>test has {{ quantity }}</p>
这是预期的结果。
希望它会有所帮助。此解决方案不适用于列表,但我认为可以扩展该解决方案。如果需要,您还可以获取缺失字段的列表。
答案 2 :(得分:0)
使用default built-in filter可以实现。
<p>{{name|default('{{name}}')}} has {{quantity|default('{{quantity}}')}}</p>
缺点是代码变得更加丑陋,变量名称重复,从而降低了可维护性。