В Jinja2, какой самый простой способ установить все ключи в значения словаря? - PullRequest
2 голосов
/ 28 июля 2010

У меня есть панель управления, которая содержит пространство имен для контекста каждого элемента панели.Есть ли быстрый способ, которым я могу установить все значения словаря для ключей в шаблоне?

Я хочу использовать шаблоны и не всегда использовать пространство имен для моих переменных.

Мой контекст можно упростить, чтобы он выглядел примерно так:

{
 "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 %}

Но они имеют только область видимости в цикле for, поэтому они не ограничены областью включения...

Ответы [ 2 ]

4 голосов
/ 28 июля 2010

Короче говоря: вы не можете устанавливать произвольные переменные в контексте. {% set key = value %} просто устанавливает переменную с именем key на заданное значение.

Причина в том, что Jinja2 компилирует шаблоны вплоть до кода Python. (Если вы хотите увидеть код, сгенерированный вашим шаблоном, загрузите скрипт по адресу http://ryshcate.leafstorm.us/paste/71c95831ca0f1d5 и передайте ему имя вашего шаблона.) Чтобы ускорить обработку, он создает локальные переменные для каждой переменной, которую вы используете в шаблоне ( только поиск переменной в контексте при первом ее обращении), в отличие от Django, который использует контекст для всех поисков переменных.

Чтобы правильно сгенерировать этот код, он должен иметь возможность отслеживать, какие локальные или глобальные переменные существуют в любой момент времени, поэтому он знает, когда искать в контексте. И установка случайных переменных не позволит этому работать, поэтому contextfunction не разрешено изменять контекст, просто просмотрите его.

Что бы я сделал, вместо того, чтобы код, отображающий бизнес, был включенным шаблоном, был ли он макросом в другом шаблоне. Например, в businesses.html:

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

А потом в вашем основном шаблоне:

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

Или, что еще лучше, разделите их на два отдельных макроса - один для предприятий и один для новых рекламных акций. Вы можете увидеть множество интересных трюков с шаблонами на http://bitbucket.org/plurk/solace/src/tip/solace/templates/, и, конечно же, проверить документацию Jinja2 на http://jinja.pocoo.org/2/documentation/templates.

1 голос
/ 28 июля 2010

Я нашел обходной путь - создав функцию контекста, я могу визуализировать шаблон и напрямую установить контекст или объединить контекст (хотя не уверен, что это хорошая практика).

@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) }}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...