从jinja模板中定义默认变量值的Sane方法?

Mat*_*son 12 python jinja2

我想为模板本身内部的Jinja模板中使用的变量设置默认值.看看Jinja2文档,我认为没有办法做到这一点.我错过了什么吗?我看到了"默认"过滤器,但我希望将值模板设置为宽而不是逐个使用.

我花了一个小时左右的时间尝试自学足够的Jinja2扩展编写过程来编写扩展标记setdefault,看起来像这样:

{% setdefault animal = 'wumpas' %}
Run Code Online (Sandbox Code Playgroud)

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')
Run Code Online (Sandbox Code Playgroud)

那么,有没有办法在库存中使用等效的Jinja2,或者如何编写扩展来实现所需的效果呢?

小智 25

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

t = '''Hello {{name | default('John Doe')}}'''
Run Code Online (Sandbox Code Playgroud)

  • "default"是为了这个目的创建的,应该是接受的答案,恕我直言.另一个习惯用法是在模板顶部使用`default`和`set`.ala`{%set name = name | default('John Doe')%}`.现在,您可以在整个模板中自由使用`name`,而不必担心它是未定义的. (3认同)

小智 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()
Run Code Online (Sandbox Code Playgroud)

正如所料,它输出:

Hello Jonnie Doe
Hello John Doe
Run Code Online (Sandbox Code Playgroud)