我想设置变量值,但仅在尚未分配和在本地上下文中时。
因此,有一个解决方案:
{% with x=( x | default(1)) %}
{{ x }}
{% endwith %}
{% with x=2 %}
{% with x=( x | default(1)) %}
{{ x }}
{% endwith %}
{% endwith %}
这很好地工作了,但这是很多文本。我有很多情况,我只有一个,但最多有20个变量正在设置,然后称为宏,或将这些值随附一个模板。
编写所有这些默认条件只是一团糟,并且会引起错误。因此,我很想能够在当前上下文中设定价值。在上下文功能中。但是,如果我尝试以下操作:
@contextfunction
def defaults(ctx, **vals):
for k,v in vals.iteritems():
if k not in ctx:
ctx[k] = v
我得到一个例外:
typeError:'上下文'对象不支持项目分配
试图在ctx.vars上设置值也不会有帮助:
vars
模板本地变量。此列表包含来自父范围以及本地的环境和上下文功能 来自模板的修改和导出变量。模板 将在模板评估期间修改此命令,但过滤器和 上下文功能不允许修改它。
http://jinja.pocoo.org/docs/2.9/api/#jinja2.context.vars
我尝试了
@contextfunction
def defaults(ctx, **vals):
for k,v in vals.iteritems():
if k not in ctx.vars:
ctx.vars[k] = v
也没有例外,但似乎只是没有将值分配给上下文。
我知道我可以写入全球环境,但这不是我想做的,因为它会产生副作用。
是否有可能仅获得当前上下文并为其设置价值?我没有找到任何说明,以及如何做到这一点,我并没有真正掌握阅读Jinja来源的那样。
我找到了一个解决方案,不知何故我一直在解决自己的问题。这并不是对问题的答案:"我如何在jinja上下文功能中设置(非全球)变量?" ,但它解决了问题。
我写了一个jinja扩展名,它允许一个简单的"默认"标签:
from jinja2 import nodes
from jinja2.ext import Extension
"""
DefaultExtension
~~~~~~~~~~~~~~~~
Very simple jinja extension that allows for the following
{% set x=(x | default(1)) %}
{% set y=(y | default(2)) %}
to be written as
{% default x=1, y=2 %}
:copyright: (c) 2017 by the Roman Seidl
:license: BSD
"""
class DefaultExtension(Extension):
# a set of names that trigger the extension.
tags = set(['default'])
def parse(self, parser):
#just dump the tag
lineno = next(parser.stream).lineno
#parse through assignments (similar to parser.parse_with)
assignments = []
while parser.stream.current.type != 'block_end':
lineno = parser.stream.current.lineno
if assignments:
parser.stream.expect('comma')
target = parser.parse_assign_target()
parser.stream.expect('assign')
expr = (parser.parse_expression())
#consruct a 'default' filter
filter = nodes.Filter(nodes.Name(target.name, 'load'), 'default', [expr], [], None, None, lineno=lineno)
#produce an assignment with this filter as value
assignment = nodes.Assign(target, filter, lineno=lineno)
assignments.append(assignment)
return assignments
我只需要将其添加到我的应用中:
app.jinja_env.add_extension(DefaultExtension)
它的效果很好,尽管我必须承认我尚未对其进行彻底的测试。
有人认为我应该将其提交给Jinja?