Шаблоны
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
Эти переменные добавляются в контекст переменных, они не являются глобальными переменными. Разница в том, что по умолчанию они не отображаются в контексте импортированных шаблонов. Это отчасти вызвано соображениями производительности, отчасти для того, чтобы всё было явно.
Что это означает для вас? Если у вас есть макрос, который вы хотите импортировать, и которому нужно обратиться к объекту запроса, у вас есть два варианта:
- Вы явно передаёте запрос макросу в качестве параметра или атрибута объекта запроса, который вас интересует.
- Вы импортируете макрос «с контекстом».
Импорт с контекстом выглядит так:
{% 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/3.0.x/templating/