Spec-Zone.ru › Flask

Шаблоны

Flask использует Jinja2 в качестве движка шаблонов. Вы, очевидно, можете использовать другой движок шаблонов, но вам всё равно необходимо установить Jinja2 для работы самого Flask. Это требование необходимо для включения расширений. Расширение может зависеть от наличия Jinja2.

Этот раздел содержит лишь очень краткое введение в то, как Jinja2 интегрируется в Flask. Если вы хотите получить информацию о синтаксисе самого движка шаблонов, обратитесь к официальной документации по шаблонам Jinja2 для получения дополнительной информации.

Настройка Jinja

Если не настраивать иначе, Jinja2 настраивается Flask следующим образом:

  • автоэкранирование включено для всех шаблонов, оканчивающихся на .html, .htm, .xml, .xhtml, а также .svg при использовании render_template().
  • автоэкранирование включено для всех строк при использовании render_template_string().
  • шаблон может включать/отключать автоэкранирование с помощью тега {% autoescape %}.
  • Flask добавляет несколько глобальных функций и вспомогательных функций в контекст Jinja2, помимо значений, присутствующих по умолчанию.

Стандартный контекст

Следующие глобальные переменные доступны в шаблонах Jinja2 по умолчанию:

config

Текущий объект конфигурации (flask.Flask.config)

Журнал изменений

Изменено в версии 0.10: Теперь он всегда доступен, даже в импортированных шаблонах.

Добавлен в версии 0.6.

request

Текущий объект запроса (flask.request). Эта переменная недоступна, если шаблон был рендерирован без активного контекста запроса.

session

Текущий объект сессии (flask.session). Эта переменная недоступна, если шаблон был рендерирован без активного контекста запроса.

g

Связанный с запросом объект для глобальных переменных (flask.g). Эта переменная недоступна, если шаблон был рендерирован без активного контекста запроса.

url_for()

Функция flask.url_for().

get_flashed_messages()

Функция flask.get_flashed_messages().

Поведение контекста Jinja

Эти переменные добавляются в контекст переменных, а не являются глобальными переменными. Разница в том, что по умолчанию они не будут отображаться в контексте импортированных шаблонов. Это частично связано с соображениями производительности, частично для ясности.

Что это значит для вас? Если у вас есть макрос, который вы хотите импортировать и которому нужен объект запроса, у вас есть два варианта:

  1. явно передайте запрос в макрос в качестве параметра или атрибут объекта запроса, который вас интересует.
  2. импортируйте макрос «с контекстом».

Импорт с контекстом выглядит так:

{% from '_helpers.html' import my_macro with context %}

Управление автоэкранированием

Автоэкранирование — это концепция автоматического экранирования специальных символов. Специальные символы в HTML (или XML, и, следовательно, XHTML) — это &, >, <, " а также ' . Поскольку эти символы имеют определённый смысл в документах сами по себе, их необходимо заменить так называемыми «сущностями», если вы хотите использовать их для текста. Отсутствие этого не только вызовет неудобство у пользователя из-за невозможности использования этих символов в тексте, но также может привести к проблемам безопасности (см. Перехват межсайтовых сценариев (XSS)).

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

Существует три способа этого:

  • В коде Python оберните строку HTML в объект Markup перед передачей её шаблону. Это, как правило, рекомендуемый способ.
  • Внутри шаблона используйте фильтр |safe для явного обозначения строки как безопасного HTML ({{ myvariable|safe }})
  • Временно отключить систему автоэкранирования.

Для отключения системы автоэкранирования в шаблонах можно использовать блок {% autoescape %}:

{% autoescape false %}
    <p>autoescaping is disabled here
    <p>{{ will_not_be_escaped }}
{% endautoescape %}

При выполнении этой операции будьте очень осторожны с переменными, которые вы используете в этом блоке.

Регистрация фильтров

Если вы хотите зарегистрировать собственные фильтры в Jinja2, у вас есть два способа. Вы можете либо вручную поместить их в jinja_env приложения, или использовать декоратор template_filter().

Два следующих примера работают одинаково, и оба инвертируют объект:

@app.template_filter('reverse')
def reverse_filter(s):
    return s[::-1]

def reverse_filter(s):
    return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter

В случае с декоратором аргумент является необязательным, если вы хотите использовать имя функции в качестве имени фильтра. После регистрации вы можете использовать фильтр в своих шаблонах так же, как встроенные фильтры Jinja2, например, если у вас есть список Python в контексте, называемый mylist:

{% for x in mylist | reverse %}
{% endfor %}

Обработчики контекста

Для автоматической инъекции новых переменных в контекст шаблона в Flask существуют обработчики контекста. Обработчики контекста выполняются перед рендерингом шаблона и имеют возможность вводить новые значения в контекст шаблона. Обработчик контекста — это функция, которая возвращает словарь. Ключи и значения этого словаря затем объединяются с контекстом шаблона для всех шаблонов в приложении:

@app.context_processor
def inject_user():
    return dict(user=g.user)

Обработчик контекста выше делает переменную под названием user доступной в шаблоне со значением g.user. Этот пример не очень интересен, потому что g доступен в шаблонах, но он дает представление о том, как это работает.

Переменные не ограничиваются значениями; обработчик контекста также может сделать доступными функции для шаблонов (поскольку Python позволяет передавать функции):

@app.context_processor
def utility_processor():
    def format_price(amount, currency="€"):
        return f"{amount:.2f}{currency}"
    return dict(format_price=format_price)

Обработчик контекста выше делает функцию format_price доступной для всех шаблонов:

{{ format_price(0.33) }}

Вы также могли бы создать format_price как фильтр шаблона (см. Регистрация фильтров), но это демонстрирует, как передавать функции в обработчике контекста.

Потоковая передача

Полезно не рендерить весь шаблон как одну полную строку, а вместо этого рендерить его как поток, возвращая более мелкие фрагменты строк. Это можно использовать для потоковой передачи HTML частями для ускорения первоначальной загрузки страницы или для экономии памяти при рендеринге очень большого шаблона.

Движок шаблонов Jinja2 поддерживает рендеринг шаблона по частям, возвращая итератор строк. Flask предоставляет функции stream_template() и stream_template_string() для упрощения использования.

from flask import stream_template

@app.get("/timeline")
def timeline():
    return stream_template("timeline.html")

Эти функции автоматически применяют обёртку stream_with_context(), если запрос активен, поэтому она остаётся доступной в шаблоне.

© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/stable/templating/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API