2013-07-29 204 views
6
{% set disabled = '' %} 
{% for voter in record.voters %} 
    {% if user == voter %} 
     {% set disabled = 'disabled' %} 
    {% endif %} 
    {{ disabled }} # outputs: 'disabled' 
{% endfor %} 
{{ disabled }} # outputs: '' 

我在Jinja2中有该模板。 我需要的是'禁用'变量在'循环'外可见。 这可能吗?Jinja2:本地/全局变量

回答

10

处理最简单的方法是将将disabled变量设置为您的视图函数并将其发送到可以使用的模板的逻辑。将应用程序逻辑与演示混合并不是一个好主意,模板应该尽可能地消化数据。

这就是说,有一个丑陋的黑客,使你想要的可能,在接受的答案this question中显示。

解决方案包括启用Jinja2的do扩展并使用它来修改全局数组。要启用扩展使用:

app.jinja_env.add_extension('jinja2.ext.do') 

这里是适合您的示例中的解决方案:

{% set disabled = [] %} 
{% for voter in record.voters %} 
    {% if user == voter %} 
     {% do disabled.append(1) %} 
    {% endif %} 
{% endfor %} 
{% if disabled %} 
    disabled 
{% endif %} 
+0

thx 。我已经修改了我的代码,并且首先按照您的建议做了。 –

0

默认块可能无法从外部范围内访问变量,您可以通过使用scoped修改像这样覆盖此:

{% for item in list scoped %} 
{% endfor %} 

参见:http://jinja.pocoo.org/docs/templates/#block-nesting-and-scope

+1

这没有做到! 'Scoped'适用于不为循环的块 –

+0

@ c00p3r.web在这种情况下,我建议为jinja2开放一个问题,因为这似乎是所需的功能:https://github.com/mitsuhiko/jinja2/issues –

6

像米格尔建议您可以使用数组/字典,但你并不需要做的扩展本身;你可以设置一个虚拟变量。我用的是以下情况:

{% set glob={} %} 

在顶部,然后在我的代码:

{% set _ = glob.update({'disabled':True}) %} 

的_变量只是一个虚拟的,这之后您没有使用它。

0

我意识到我正在回答一个旧线程。但是,最近我开始使用Jinja并遇到类似的问题:我需要计算嵌套循环中打印行的数量。我的解决方案是在一个类中包装一个计数器变量并将一个实例传递给模板。同样,你可以使用一个包装类,像这样

class VoterStatus(object): 
    def __init__(self, status='active'): 
     self._status = status 

    def set_disabled(self): 
     self._status = 'disabled' 

    def __str__(self): 
     return self._status 

修改模板相应

{% for voter in record.voters %} 
    {% if user == voter %} 
     {% status.set_disabled() %} 
    {% endif %} 
    {{ status }} # outputs: 'disabled' 
{% endfor %} 

传递一个状态类实例的模板渲染:

tmplt.render(status=VoterStatus(), ...) 

...鲍勃是你的叔叔。