Flask использует в качестве системы шаблонизации Jinja2. Можно использовать другие системы шаблонизации, но для запуска Flask всё равно необходимо установить Jinja2. Это необходимо для использования дополнительных возможностей. Расширения могут зависеть от наличия Jinja2.
Этот раздел предоставляет лишь краткое описание интеграции Jinja2 во Flask. Если вам нужна информация о синтаксисе самой системы шаблонизации, за более подробной информацией обратитесь к официальной документации по шаблонам Jinja2.
Установка Jinja
По умолчанию Flask настраивает Jinja2 следующим образом:
- включено автоматическое экранирование для всех шаблонов, с раширениями .html, .htm, .xml, .xhtml
- шаблон может включать или отключать автоматическое экранирование при помощи тега {% autoescape %}.
- Flask добавляет пару функций и хелперов в контекст Jinja2, дополнительно к значениям, имеющимся по умолчанию.
По умолчанию из шаблонов Jinja2 доступны следующие глобальные переменные:
config | Объект текущей конфигурации (flask.config) Новинка версии 0.6. |
---|---|
request | Объект текущего запроса (flask.request) |
session | Объект текущего сеанса (flask.session) |
g | Связанный с запросом объект с глобальными переменными (flask.g) |
url_for() | Функция flask.url_for() |
get_flashed_messages() | Функция flask.get_flashed_messages() |
Контекстное поведение Jinja
Эти переменные добавляются к переменным контекста, но это не глобальные переменные. Отличие заключается в том, что по умолчанию эти переменные отсутствуют в контексте импортируемых шаблонов. Отчасти это сделано для повышения производительности, отчасти - из-за предпочтения явного поведения неявному.
Какое это имеет значение? Если вам нужно получить доступ из макроса к объекту запроса, есть две возможности:
- явным образом передать объект запроса или его атрибут в макрос в качестве параметра.
- импортировать макрос с контекстом, указав ключевые слова "with context".
{% from '_helpers.html' import my_macro with context %}Стандартные фильтры
В дополнение к собственным фильтрам Jinja2, доступны следующие фильтры:
tojson()
Эта функция конвертирует переданный объект в JSON-представление. Это может быть полезно, когда нужно на лету сгенерировать JavaScript.
Отметим, что внутри тегов script не должно производиться экранирование, поэтому убедитесь в том, что отключили экранирование при помощи фильтра |safe, если собираетесь использовать фильтр tojson внутри тегов script:
<script type=text/javascript> doSomethingWith({{ user.username|tojson|safe }}); </script>
Фильтр |tojson правильно экранирует прямую косую черту.
Управление автоэкранированием
Автоэкранирование - это автоматическое экранирование специальных символов. Специальными символами в HTML (а также в XML и в XHTML) являются &, >, <, " и '. Поскольку эти символы имеют особое значение в документах, для использования в тексте их нужно заменить на так называемые "сущности". Если этого не сделать, это не только может повлиять на невозможность использования этих символов пользователем, но и привести к проблемам с безопасностью (см. Кросс-сайтовый скриптинг - XSS).
Однако, иногда в шаблонах может потребоваться отключить автоэкранирование. Это может понадобиться, если нужно явным образом вставить в страниц фрагмент HTML, если фрагмент поступил из системы генерации безопасного HTML, например, из преобразователя markdown в HTML.
Для достижения этого есть три способа:
- В коде Python обернуть строку HTML в объект Markup перед передачей в шаблон. Это рекомендуемый способ.
- Внутри шаблона, воспользовавшись фильтром |safe для явной отметки строки, как безопасного HTML ({{ myvariable|safe }})
- Временно отключить систему автоэкранирования.
{% autoescape false %} <p>здесь автоэкранирование отключено <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:
@app.context_processor def inject_user(): return dict(user=g.user)Процессор контекста, приведённый выше, сделает переменную g.user доступной из шаблона под именем user. Этот пример не очень интересен, поскольку g и так доступна в шаблонах, но даёт представление о том, как это работает.
Процессор контекста может передавать в шаблон не только переменные, но и функции (поскольку Python позволяет передавать функции):
@app.context_processor def utility_processor(): def format_price(amount, currency=u'€'): return u'{0:.2f}{1}.format(amount, currency) return dict(format_price=format_price)Вышеприведённый процессор контекста передаст функцию format_price во все шаблоны:
{{ format_price(0.33) }}Вы также можете встроить format_price как фильтр шаблона (см. выше раздел Регистрация фильтров), но этот пример демонстрирует, как передавать функции в контекст шаблона.
Примечания переводчика
Этот и другие переводы можно найти на сайте проекта перевода документации по Flask. Автор проекта - Виталий Кузьмин aka ferm32.
Комментариев нет:
Отправить комментарий