Шаблоны
Flask использует Jinja2 в качестве движка шаблонов. Вы, очевидно, можете использовать другой движок шаблонов, но вам всё равно нужно установить Jinja2 для запуска самого Flask. Это требование необходимо для включения расширенных возможностей. Расширение может зависеть от наличия Jinja2.
Этот раздел предоставляет только очень краткое введение в то, как Jinja2 интегрирован в Flask. Если вы хотите получить информацию о синтаксисе самого движка шаблонов, перейдите на официальную документацию Jinja2 Template Documentation для получения дополнительной информации.
Настройка 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 %}
Стандартные фильтры
Flask предоставляет следующие фильтры 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.1.x/templating/