2010-07-28 24 views
2

我已经为每个仪表板项目命名空间的上下文。有没有一种方法可以将字典的所有值设置为模板中的键?在Jinja2中,最简单的方法是将所有键设置为字典的值?

我想重用模板,而不是总是命名空间我的变量。

我的情况下可以简化为是这个样子:

{ 
"business": {"businesses": [], "new_promotions": []}, 
"messages": {"one_to_one": [], "announcements": [] 
} 

所以在with语句我想将所有的商务项目是本地的,包括。要做到这一点目前我有单独设置每个变量:

{% with %} 
    {% set businesses = business["businesses"] %} 
    {% set new_promotions = business["new_promotions"] %} 
    {% include "businesses.html" %} 
{% endwith %} 

我想:

{% with %} 
    {% for key, value in my_dict %} 
    {% set key = value %} 
    {% endfor %} 
    {% include "businesses.html" %} 
{% endwith %} 

,但他们只在该范围内的循环,这样不会在包括...

作用域

回答

4

长话短说:你可以不设置任何变量的情况下。 {% set key = value %}只是将名为key的变量设置为给定值。

原因是Jinja2将模板编译为Python代码。 (如果您想查看模板生成的代码,请在http://ryshcate.leafstorm.us/paste/71c95831ca0f1d5下载脚本并将模板文件名传递给它。)为了使处理速度更快,它为您在模板中使用的每个变量创建局部变量(只查找变量在上下文中第一次遇到),而不是Django,它使用上下文进行所有变量查找。

为了正确生成此代码,它需要能够跟踪哪些局部或全局变量存在于任何给定时间,因此它知道何时在上下文中查找。并且设置随机变量会阻止这个工作,这就是为什么contextfunction s不允许修改上下文,只是查看它。

但是,我会做的是,而不是让您的业务显示代码是一个包含的模板,是让它成为另一个模板中的宏。例如,在businesses.html

{% macro show_businesses(businesses, new_promotions) %} 
    {# whatever you're displaying... #} 
{% endmacro %} 

然后在你的主模板:

{% from "businesses.html" import show_businesses %} 
{% show_businesses(**businesses) %} 

或者,更好的是,他们分为2层独立的宏 - 一个为企业和一个新的促销活动。您可以在http://bitbucket.org/plurk/solace/src/tip/solace/templates/处看到很多很酷的模板窍门,当然也可以查看http://jinja.pocoo.org/2/documentation/templates上的Jinja2文档。

+0

感谢LeafStorm提供的见解和示例。 business.html模板已经使用宏,但并非所有的仪表板项目都可以使用,但您完全正确,可以将业务逻辑和显示分开。 在这种情况下,对我来说,我认为有一个contextfunction根据传递的上下文输出模板是可取的,因为它意味着更少的模板代码,并保持干燥。 – Ross 2010-07-29 09:39:54

+0

为什么我不能做{%set show ['otherdetails'] = true%} – aWebDeveloper 2014-06-04 06:58:14

1

我找到了解决办法 - 通过创建一个上下文功能,我可以渲染模板,并直接设置上下文或合并上下文(不知道这是很好的做法,虽然)。

@jinja2.contextfunction 
def render(context, template_name, extra_context, merge=False): 
    template = jinja_env.get_template(template_name) 

    # Merge or standalone context? 
    if merge: 
     ctx = context.items() 
     ctx.update(extra_context) 
    else: 
     ctx = extra_context 

    return jinja2.Markup(template.render(ctx)) 

所以我的模板看起来像:

{{ render("businesses.html", business) }} 
相关问题