13

我想在模板本身内部为我的 Jinja 模板中使用的变量设置默认值。查看 Jinja2 文档,我没有看到任何方法可以做到这一点。我错过了什么吗?我看到了“默认”过滤器,但我想将值模板设置为广泛而不是按使用方式设置。

我花了一个小时左右的时间试图自学足够的关于 Jinja2 扩展编写过程的知识来编写扩展标签setdefault,它可能看起来像这样:

{% setdefault animal = 'wumpas' %}

如果未定义分配给名称,则所需效果将等效于set标记,但如果已定义分配给名称,则没有效果。到目前为止,我还没有让它发挥作用。

我的工作是完全绕过 jinja 并制作一个复合文件;特殊标记之前的区域是默认值的(yaml)映射,标记之后的区域是 jinja 模板。似乎可以正常工作的概念验证实现是:

skel_text = """\
animal: wumpas
%%
The car carried my {{animal}} to the vet.
"""
class Error(Exception): pass
_skel_rx = re.compile(
    r"""((?P<defaults>.*?)^%%[ \t]*\n)?(?P<template>.*)""",
    re.MULTILINE|re.DOTALL)
_env = jinja2.Environment(trim_blocks=True)
def render(skel, **context):
    m = _skel_rx.match(skel_text)
    if not m:
        raise Error('skel split failed')
    defaults = yaml.load(m.group('defaults') or '{}')
    template = _env.from_string(m.group('template') or '')
    template.globals.update(defaults)
    return template.render(**context)

print render(skel_text)
print render(skel_text, animal='cat')

那么,有没有办法在股票 Jinja2 中做同样的事情,或者如何编写扩展来达到预期的效果?

4

3 回答 3

27

对我有用的是使用过滤器:

t = '''Hello {{name | default('John Doe')}}'''
于 2013-10-29T16:27:31.470 回答
14

设置控制结构可以做你想做的事。

这是我用来测试的一些代码:

from jinja2 import Template
t = '''{% set name=name or "John Doe" %}Hello {{ name }}'''
template = Template(t)
print template.render(name='Jonnie Doe')
print template.render()

正如预期的那样,它输出:

Hello Jonnie Doe
Hello John Doe
于 2010-12-18T20:34:30.667 回答
0

只是为了更新,如果变量“失败”,Jinja2 中有一种方法可以将默认值设置为变量。失败,我们的意思是他们没有价值。

{{ variable | default(0) }}

如果变量的值未提供给模板,此代码会将变量的值设置为 0。如果您的变量是字典,那么您可以使用以下代码:

{{ dict['key'] | default(0) }}

在这种情况下,如果 dict['key'] value 没有定义或者 'key' 首先不存在,那么它的 value 将被设置为 0。

有关更多信息,请查看:Jinja2 过滤器文档

于 2021-12-27T06:12:06.260 回答