2010-07-28 5 views
2

J'ai un tableau de bord qui répertorie le contexte pour chaque élément du tableau de bord. Existe-t-il un moyen rapide de définir toutes les valeurs d'un dictionnaire sur les clés d'un modèle?Dans Jinja2 quel est le moyen le plus simple de définir toutes les clés pour être les valeurs d'un dictionnaire?

Je souhaite réutiliser des modèles et pas toujours mes espaces de noms.

Mon contexte peut être simplifié pour ressembler à quelque chose comme ceci:

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

Ainsi, dans une déclaration avec je veux mettre tous les éléments d'affaires être local pour l'y compris. Pour ce faire, actuellement je dois régler chaque variable individuellement:

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

J'ai essayé:

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

Mais ils n'ont une portée dans la boucle ne sont donc pas dans le scope comprennent ...

Répondre

4

longue histoire courte: vous ne pouvez pas définir des variables arbitraires dans le contexte. Le {% set key = value %} définit simplement la variable nommée key à la valeur donnée. La raison en est que Jinja2 compile les modèles en code Python. (Si vous voulez voir le code généré par votre modèle, téléchargez le script au http://ryshcate.leafstorm.us/paste/71c95831ca0f1d5 et transmettez le nom de fichier de votre modèle.) Afin de rendre le traitement plus rapide, il crée des variables locales pour chaque variable que vous utilisez dans le modèle. dans le contexte la première fois qu'il est rencontré), par opposition à Django, qui utilise le contexte pour toutes les recherches de variables. Pour générer ce code correctement, il doit être capable de suivre quelles variables locales ou globales existent à un moment donné, ainsi il sait quand rechercher dans le contexte. Et la définition de variables aléatoires empêcherait cela de fonctionner, ce qui explique pourquoi les contextfunction ne sont pas autorisés à modifier le contexte, il suffit de l'afficher. Ce que je ferais, cependant, est que le code d'affichage de votre entreprise soit un modèle inclus, c'est une macro dans un autre modèle. Par exemple, dans businesses.html:

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

Et puis dans votre modèle principal:

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

Ou, mieux encore, de les séparer en deux macros distinctes - une pour les entreprises, et un pour les nouvelles promotions. Vous pouvez voir beaucoup d'astuces de modèle cool au http://bitbucket.org/plurk/solace/src/tip/solace/templates/, et bien sûr vérifier la documentation Jinja2 au http://jinja.pocoo.org/2/documentation/templates.

+0

Merci LeafStorm pour vos idées et les exemples. Le modèle business.html utilise déjà des macros, mais pas tous les éléments du tableau de bord, mais vous avez tout à fait raison: il est bon de diviser la logique métier et l'affichage. Dans ce cas et pour moi, je pense qu'il est préférable d'avoir une fonction de contexte qui génère le modèle basé sur le contexte passé car cela signifie moins de code de modèle et garde les choses au sec. – Ross

+0

pourquoi ne puis-je faire {% set show ['otherdetails'] = true%} – aWebDeveloper

1

J'ai trouvé un travail - en créant une fonction de contexte je peux rendre le modèle et directement définir le contexte ou fusionner le contexte (pas sûr que c'est une bonne pratique cependant).

@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)) 

Alors mes modèles ressemblent:

{{ render("businesses.html", business) }} 
Questions connexes