Шаблоны
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.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–2021 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.0.x/templating/