Шаблоны
Flask использует Jinja2 в качестве движка шаблонов. Вы, очевидно, можете использовать другой движок шаблонов, но вам все равно нужно установить Jinja2, чтобы запустить Flask. Это требование необходимо для включения расширений. Расширение может зависеть от наличия Jinja2.
Этот раздел предоставляет только очень краткое введение в то, как Jinja2 интегрирован в Flask. Если вы хотите получить информацию о синтаксисе самого движка шаблонов, перейдите к официальной документации по шаблонам Jinja2 для получения дополнительной информации.
Настройка Jinja
Если не настраивается иначе, Jinja2 настраивается Flask следующим образом:
- автоэкранирование включено для всех шаблонов, заканчивающихся на
.html,.htm,.xmlа также.xhtmlпри использовании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 как фильтр шаблона (см. Регистрация фильтров), но это демонстрирует, как передавать функции в обработчике контекста.
© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.1.x/templating/