Шаблоны
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 %}
Стандартные фильтры
Эти фильтры доступны в Jinja2 помимо фильтров, предоставляемых самим Jinja2:
-
tojson() -
Эта функция преобразует заданный объект в представление JSON. Это, например, очень полезно, если вы пытаетесь сгенерировать JavaScript на лету.
<script type=text/javascript> doSomethingWith({{ user.username|tojson }}); </script>Также безопасно использовать вывод
|tojsonв атрибуте HTML с одинарными кавычками:<button onclick='doSomethingWith({{ user.username|tojson }})'> Click me </button>Обратите внимание, что в версиях Flask до 0.10, если вы используете вывод
|tojsonвнутриscript, убедитесь, что отключена экранизация с помощью|safe. В Flask 0.10 и выше это происходит автоматически.
Управление автоматической экранизацией
Автоматическая экранизация — это концепция автоматической экранизации специальных символов. Специальные символы в смысле 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=u'€'):
return u'{0:.2f}{1}'.format(amount, currency)
return dict(format_price=format_price)
Обработчик контекста выше делает функцию format_price доступной для всех шаблонов:
{{ format_price(0.33) }}
Вы также могли бы создать format_price как фильтр шаблона (см. Регистрация фильтров), но это демонстрирует, как передавать функции в обработчике контекста.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.0.x/templating/