Spec-Zone.ru › Jinja 2.11

API

Этот документ описывает API для Jinja, а не сам язык шаблонов (для этого см. Документация для разработчиков шаблонов). Он будет наиболее полезен в качестве справочника для тех, кто реализует интерфейс шаблонов для приложения, а не для тех, кто создает шаблоны Jinja.

Основы

Jinja использует центральный объект, называемый шаблоном Environment. Экземпляры этого класса используются для хранения конфигурации и глобальных объектов, а также для загрузки шаблонов из файловой системы или других местоположений. Даже если вы создаете шаблоны из строк, используя конструктор класса Template, среда создается для вас автоматически, хотя и общая.

В большинстве приложений создается один объект Environment при инициализации приложения, и он используется для загрузки шаблонов. Однако в некоторых случаях полезно иметь несколько сред одновременно, если используются разные конфигурации.

Простейший способ настроить Jinja для загрузки шаблонов для вашего приложения выглядит примерно так:

from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(
    loader=PackageLoader('yourapplication', 'templates'),
    autoescape=select_autoescape(['html', 'xml'])
)

Это создаст среду шаблонов с настройками по умолчанию и загрузчиком, который ищет шаблоны в папке templates внутри пакета python yourapplication. Доступны различные загрузчики, и вы также можете написать свой собственный, если хотите загружать шаблоны из базы данных или других ресурсов. Это также включает автоэкранирование для файлов HTML и XML.

Чтобы загрузить шаблон из этой среды, вам просто нужно вызвать метод get_template(), который затем возвращает загруженный Template:

template = env.get_template('mytemplate.html')

Чтобы отобразить его с некоторыми переменными, просто вызовите метод render().

print(template.render(the='variables', go='here'))

Использование загрузчика шаблонов, а не передача строк в Template или Environment.from_string(), имеет множество преимуществ. Помимо того, что это намного проще в использовании, это также позволяет использовать наследование шаблонов.

Примечания по автоэкранированию

В будущих версиях Jinja мы можем включить автоэкранирование по умолчанию в целях безопасности. Поэтому вам рекомендуется явно настроить автоэкранирование сейчас, а не полагаться на значение по умолчанию.

Unicode

Jinja использует Unicode внутри, а это значит, что вы должны передавать объекты Unicode в функцию render или байтовые строки, которые состоят только из символов ASCII. Кроме того, символы новой строки нормализуются до одной последовательности конца строки, которая по умолчанию имеет стиль UNIX (\n).

Python 2.x поддерживает два способа представления строковых объектов. Один — это тип str, а другой — тип unicode, оба из которых расширяют тип, называемый basestring. К сожалению, значением по умолчанию является str, который не следует использовать для хранения текстовой информации, если используются только символы ASCII. С Python 2.6 можно сделать unicode значением по умолчанию на уровне модуля, а с Python 3 это будет значением по умолчанию.

Чтобы явно использовать строку Unicode, вы должны добавить префикс к строковой литералу с помощью u: u'Hänsel und Gretel sagen Hallo'. Таким образом, Python будет хранить строку как Unicode, декодируя строку с помощью кодировки символов из текущего модуля Python. Если кодировка не указана, это значение по умолчанию равно «ASCII», а это значит, что вы не можете использовать никакие не ASCII идентификаторы.

Чтобы установить лучшую кодировку модуля, добавьте следующий комментарий в первую или вторую строку модуля Python, используя Unicode литерал:

# -*- coding: utf-8 -*-

Мы рекомендуем utf-8 в качестве кодировки для модулей Python и шаблонов, поскольку в utf-8 можно представить каждый символ Unicode, и потому что он обратно совместим с ASCII. Для Jinja предполагается, что кодировка шаблонов по умолчанию — utf-8.

Невозможно использовать Jinja для обработки данных, не являющихся Unicode. Причина этого в том, что Jinja уже использует Unicode на уровне языка. Например, Jinja обрабатывает неразрывный пробел как допустимый пробел внутри выражений, что требует знания кодировки или работы со строкой Unicode.

Для получения дополнительной информации о Unicode в Python ознакомьтесь с отличной документацией по Unicode.

Еще одна важная вещь — это то, как Jinja обрабатывает строковые литералы в шаблонах. Наивной реализацией было бы использование строк Unicode для всех строковых литералов, но в прошлом выяснилось, что это проблематично, поскольку некоторые библиотеки явно проверяют тип на str. Например, datetime.strftime не принимает аргументы Unicode. Чтобы не сломать его полностью, Jinja возвращает str для строк, которые подходят для ASCII, и unicode для всего остального:

>>> m = Template(u"{% set a, b = 'foo', 'föö' %}").module
>>> m.a
'foo'
>>> m.b
u'f\xf6\xf6'

API высокого уровня

API высокого уровня — это API, который вы будете использовать в приложении для загрузки и отображения шаблонов Jinja. API низкого уровня, с другой стороны, полезен только в том случае, если вы хотите глубже изучить Jinja или разработать расширения.

class jinja2.Environment([options])

Основным компонентом Jinja является Environment. Он содержит важные общие переменные, такие как конфигурация, фильтры, тесты, глобальные переменные и другие. Экземпляры этого класса могут быть изменены, если они не являются общими и если до сих пор не был загружен ни один шаблон. Изменения в средах после загрузки первого шаблона приведут к неожиданным эффектам и неопределенному поведению.

Вот возможные параметры инициализации:

block_start_string

Строка, обозначающая начало блока. По умолчанию '{%'.

block_end_string

Строка, обозначающая конец блока. По умолчанию '%}'.

variable_start_string

Строка, обозначающая начало оператора вывода. По умолчанию '{{'.

variable_end_string

Строка, обозначающая конец оператора вывода. По умолчанию '}}'.

comment_start_string

Строка, обозначающая начало комментария. По умолчанию '{#'.

comment_end_string

Строка, обозначающая конец комментария. По умолчанию '#}'.

line_statement_prefix

Если указано и является строкой, это будет использоваться в качестве префикса для операторов на основе строк. См. также Line Statements.

line_comment_prefix

Если указано и является строкой, это будет использоваться в качестве префикса для комментариев на основе строк. См. также Line Statements.

Changelog

New in version 2.2.

trim_blocks

Если это установлено в True, первая новая строка после блока удаляется (блок, а не тег переменной!). По умолчанию False.

lstrip_blocks

Если это установлено в True, ведущие пробелы и табуляции удаляются из начала строки до блока. По умолчанию False.

newline_sequence

Последовательность, которая запускает новую строку. Должно быть одним из '\r', '\n' или '\r\n'. По умолчанию '\n', что является полезным значением по умолчанию для систем Linux и OS X, а также для веб-приложений.

keep_trailing_newline

Сохранять конечную новую строку при визуализации шаблонов. Значение по умолчанию — False, что приводит к удалению одной новой строки, если она присутствует, из конца шаблона.

Changelog

New in version 2.7.

extensions

Список расширений Jinja для использования. Это могут быть пути импорта в виде строк или классы расширений. Для получения дополнительной информации см. the extensions documentation.

optimized

следует ли включать оптимизатор? По умолчанию True.

undefined

Undefined или его подкласс, который используется для представления неопределенных значений в шаблоне.

finalize

Вызываемый объект, который может использоваться для обработки результата выражения переменной перед его выводом. Например, можно преобразовать None неявно в пустую строку здесь.

autoescape

Если установлено в True, функция автоматического экранирования XML/HTML включена по умолчанию. Для получения дополнительной информации об автоматическом экранировании см. Markup. Начиная с Jinja 2.4, это также может быть вызываемый объект, которому передается имя шаблона и который должен возвращать True или False в зависимости от того, должно ли автоматическое экранирование быть включено по умолчанию.

Changelog

Changed in version 2.4: autoescape can now be a function

loader

Загрузчик шаблонов для этой среды.

cache_size

Размер кэша. По умолчанию это 400, что означает, что если загружено более 400 шаблонов, загрузчик очистит наименее часто используемый шаблон. Если размер кэша установлен в 0, шаблоны будут перекомпилироваться постоянно, если размер кэша равен -1, кэш не будет очищен.

Changelog

Changed in version 2.8: The cache size was increased to 400 from a low 50.

auto_reload

Некоторые загрузчики загружают шаблоны из мест, где исходные данные шаблонов могут изменяться (например, файловая система или база данных). Если auto_reload установлено в True (по умолчанию), каждый раз при запросе шаблона загрузчик проверяет, изменился ли источник, и если да, он перезагрузит шаблон. Для повышения производительности это можно отключить.

bytecode_cache

Если установлено в объект кэша байт-кода, этот объект будет предоставлять кэш для внутреннего байт-кода Jinja, так что шаблоны не нужно будет анализировать, если они не были изменены.

См. Bytecode Cache для получения дополнительной информации.

enable_async

Если установлено в true, это включает асинхронное выполнение шаблона, что позволяет использовать новые функции Python. Для этого требуется Python 3.6 или более поздней версии.

shared

Если шаблон был создан с помощью конструктора Template, среда создается автоматически. Эти среды создаются как общие среды, что означает, что несколько шаблонов могут иметь одну и ту же анонимную среду. Для всех общих сред этот атрибут равен True, иначе False.

sandboxed

Если среда изолирована, этот атрибут равен True. Для режима изоляции см. документацию по SandboxedEnvironment.

filters

Словарь фильтров для этой среды. Пока не загружен ни один шаблон, можно безопасно добавлять новые фильтры или удалять старые. Для пользовательских фильтров см. Custom Filters. Для допустимых имен фильтров см. Notes on Identifiers.

tests

Словарь тестовых функций для этой среды. Пока не загружен ни один шаблон, можно безопасно изменять этот словарь. Для пользовательских тестов см. Custom Tests. Для допустимых имен тестов см. Notes on Identifiers.

globals

Словарь глобальных переменных. Эти переменные всегда доступны в шаблоне. Пока не загружен ни один шаблон, можно безопасно изменять этот словарь. Для получения дополнительной информации см. The Global Namespace. Для допустимых имен объектов см. Notes on Identifiers.

policies

Словарь с Policies. Их можно перенастроить, чтобы изменить поведение во время выполнения или определенные функции шаблона. Обычно они связаны с безопасностью.

code_generator_class

Класс, используемый для генерации кода. В большинстве случаев его не следует изменять, если только вам не нужно изменить код Python, в который компилируется шаблон.

context_class

Контекст, используемый для шаблонов. В большинстве случаев его не следует изменять, если только вам не нужно изменить внутренние механизмы обработки переменных шаблона. Для получения подробной информации см. Context.

overlay([options])

Создает новую наложенную среду, которая совместно использует все данные с текущей средой, за исключением кэша и переопределенных атрибутов. Расширения не могут быть удалены для наложенной среды. Наложенная среда автоматически получает все расширения среды, к которой она подключена, плюс дополнительные необязательные расширения.

Создание наложений должно происходить после полной настройки исходной среды. Не все атрибуты действительно связаны, некоторые просто копируются, поэтому изменения в исходной среде могут не отображаться.

undefined([hint, obj, name, exc])

Создает новый объект Undefined для name. Это полезно для фильтров или функций, которые могут возвращать неопределенные объекты для некоторых операций. Все параметры, кроме hint, должны быть предоставлены в виде именованных параметров для лучшей читаемости. hint используется в качестве сообщения об ошибке для исключения, если предоставлено, в противном случае сообщение об ошибке будет сгенерировано из obj и name автоматически. Исключение, предоставленное как exc, возникает, если с созданным неопределенным объектом выполняется действие, которое неопределенный объект не допускает. Исключение по умолчанию — UndefinedError. Если предоставлен hint, name можно опустить.

Наиболее распространенный способ создания неопределенного объекта — предоставление только имени:

return environment.undefined(name='some_name')

Это означает, что имя some_name не определено. Если имя было из атрибута объекта, имеет смысл сообщить неопределенному объекту объект-владелец для улучшения сообщения об ошибке:

if not hasattr(obj, 'attr'):
    return environment.undefined(obj=obj, name='attr')

Для более сложного примера вы можете предоставить подсказку. Например, фильтр first() создает неопределенный объект таким образом:

return environment.undefined('no first item, sequence was empty')

Если name или obj известны (например, потому что был доступ к атрибуту), их следует передать неопределенному объекту, даже если предоставлен пользовательский hint. Это дает неопределенным объектам возможность улучшить сообщение об ошибке.

add_extension(extension)

Добавляет расширение после создания среды.

Журнал изменений

Новое в версии 2.5.

compile_expression(source, undefined_to_none=True)

Удобный вспомогательный метод, который возвращает вызываемый объект, принимающий именованные аргументы, которые отображаются как переменные в выражении. При вызове он возвращает результат выражения.

Это полезно, если приложения хотят использовать те же правила, что и Jinja, в файлах «конфигурации» шаблонов или аналогичных ситуациях.

Пример использования:

>>> env = Environment()
>>> expr = env.compile_expression('foo == 42')
>>> expr(foo=23)
False
>>> expr(foo=42)
True

По умолчанию возвращаемое значение преобразуется в None, если выражение возвращает неопределенное значение. Это можно изменить, установив undefined_to_none в False.

>>> env.compile_expression('var')() is None
True
>>> env.compile_expression('var', undefined_to_none=False)()
Undefined
Журнал изменений

Новое в версии 2.1.

compile_templates(target, extensions=None, filter_func=None, zip='deflated', log_function=None, ignore_errors=True, py_compile=False)

Находит все шаблоны, которые может найти загрузчик, компилирует их и сохраняет их в target. Если zip равно None, вместо zip-архива шаблоны будут храниться в каталоге. По умолчанию используется алгоритм сжатия deflate. Чтобы переключиться на алгоритм хранения, zip можно установить в 'stored'.

extensions и filter_func передаются в list_templates(). Каждый возвращаемый шаблон будет скомпилирован в целевую папку или zip-архив.

По умолчанию ошибки компиляции шаблонов игнорируются. Если предоставлена функция ведения журнала, ошибки регистрируются. Если вы хотите, чтобы синтаксические ошибки шаблона прерывали компиляцию, вы можете установить ignore_errors в False, и вы получите исключение при синтаксических ошибках.

Если py_compile установлено в True, файлы .pyc будут записаны в целевой объект вместо стандартных файлов .py. Этот флаг ничего не делает на pypy и Python 3, где файлы pyc не выбираются сами по себе и не дают большой выгоды.

Журнал изменений

Новое в версии 2.4.

extend(**attributes)

Добавляет элементы в экземпляр среды, если они еще не существуют. Это используется расширениями для регистрации обратных вызовов и значений конфигурации без нарушения наследования.

from_string(source, globals=None, template_class=None)

Загружает шаблон из строки. Это разбирает заданный источник и возвращает объект Template.

get_or_select_template(template_name_or_list, parent=None, globals=None)

Выполняет проверку типа и отправляет в select_template(), если задан итерируемый набор имен шаблонов, иначе в get_template().

Журнал изменений

Новое в версии 2.3.

get_template(name, parent=None, globals=None)

Загружает шаблон из загрузчика. Если загрузчик настроен, этот метод запрашивает у загрузчика шаблон и возвращает Template. Если параметр parent не None, вызывается join_path() для получения реального имени шаблона перед загрузкой.

Параметр globals можно использовать для предоставления глобальных переменных для всего шаблона. Эти переменные доступны в контексте во время рендеринга.

Если шаблон не существует, возникает исключение TemplateNotFound.

Журнал изменений

Изменено в версии 2.4: Если name является объектом Template, он возвращается из функции без изменений.

join_path(template, parent)

Соединяет шаблон с родителем. По умолчанию все поиски выполняются относительно корня загрузчика, поэтому этот метод возвращает параметр template без изменений, но если пути должны быть относительными к родительскому шаблону, эту функцию можно использовать для вычисления реального имени шаблона.

Подклассы могут переопределить этот метод и реализовать здесь соединение путей шаблонов.

list_templates(extensions=None, filter_func=None)

Возвращает список шаблонов для этой среды. Для этого требуется, чтобы загрузчик поддерживал метод list_templates() загрузчика.

Если в папке шаблонов есть другие файлы, помимо самих шаблонов, возвращаемый список можно отфильтровать. Есть два способа: либо extensions устанавливается в список расширений файлов для шаблонов, либо можно предоставить filter_func, который является вызываемым объектом, которому передается имя шаблона, и он должен возвращать True, если он должен попасть в результирующий список.

Если загрузчик этого не поддерживает, возникает исключение TypeError.

Журнал изменений

Новое в версии 2.4.

select_template(names, parent=None, globals=None)

Работает как get_template(), но пробует несколько шаблонов, прежде чем завершится неудачей. Если он не может найти ни один из шаблонов, он вызовет исключение TemplatesNotFound.

Изменено в версии 2.11: Если names является Undefined, вместо этого возникает исключение UndefinedError. Если шаблоны не найдены и names содержит Undefined, сообщение более информативно.

Журнал изменений

Изменено в версии 2.4: Если names содержит объект Template, он возвращается из функции без изменений.

Новое в версии 2.3.

class jinja2.Template

Центральный объект шаблона. Этот класс представляет собой скомпилированный шаблон и используется для его оценки.

Обычно объект шаблона создается из Environment, но он также имеет конструктор, который позволяет создавать экземпляр шаблона напрямую, используя конструктор. Он принимает те же аргументы, что и конструктор среды, но указать загрузчик невозможно.

Каждый объект шаблона имеет несколько методов и членов, существование которых гарантировано. Однако важно понимать, что объект шаблона следует считать неизменяемым. Изменения объекта не поддерживаются.

Объекты шаблонов, созданные из конструктора, а не из среды, имеют атрибут environment, который указывает на временную среду, которая, вероятно, совместно используется с другими шаблонами, созданными с помощью конструктора и совместимыми настройками.

>>> template = Template('Hello {{ name }}!')
>>> template.render(name='John Doe') == u'Hello John Doe!'
True
>>> stream = template.stream(name='John Doe')
>>> next(stream) == u'Hello John Doe!'
True
>>> next(stream)
Traceback (most recent call last):
    ...
StopIteration
globals

Словарь с глобальными переменными этого шаблона. Изменение этого словаря небезопасно, так как он может совместно использоваться с другими шаблонами или средой, которая загрузила шаблон.

name

Имя загрузки шаблона. Если шаблон был загружен из строки, это None.

filename

Имя файла шаблона в файловой системе, если он был загружен оттуда. В противном случае это None.

render([context])

Этот метод принимает те же аргументы, что и конструктор dict: словарь, подкласс словаря или несколько именованных аргументов. Если аргументы не указаны, контекст будет пустым. Эти два вызова делают то же самое:

template.render(knights='that say nih')
template.render({'knights': 'that say nih'})

Это вернет отрендеренный шаблон в виде unicode-строки.

generate([context])

Для очень больших шаблонов может быть полезно не рендерить весь шаблон сразу, а оценивать каждое утверждение одно за другим и получать результат по частям. Этот метод в основном делает именно это и возвращает генератор, который выдает один элемент за другим в виде unicode-строк.

Он принимает те же аргументы, что и render().

stream([context])

Работает точно так же, как generate(), но возвращает TemplateStream.

render_async([context])

Этот метод работает аналогично render(), но возвращает корутину, которая после ожидания возвращает всю отрендеренную строку шаблона. Для этого необходимо включить функцию async.

Пример использования:

await template.render_async(knights='that say nih; asynchronously')
generate_async([context])

Асинхронная версия generate(). Работает очень похоже, но возвращает асинхронный итератор.

make_module(vars=None, shared=False, locals=None)

Этот метод работает как атрибут module при вызове без аргументов, но он будет оценивать шаблон при каждом вызове, а не кэшировать его. Также можно указать словарь, который затем используется в качестве контекста. Аргументы такие же, как и для метода new_context().

property module

Шаблон как модуль. Это используется для импорта во время выполнения шаблона, но также полезно, если нужно получить доступ к экспортируемым переменным шаблона из уровня Python:

>>> t = Template('{% macro foo() %}42{% endmacro %}23')
>>> str(t.module)
'23'
>>> t.module.foo() == u'42'
True

Этот атрибут недоступен, если включен асинхронный режим.

class jinja2.environment.TemplateStream

Поток шаблона работает почти так же, как обычный генератор python, но он может буферизовать несколько элементов, чтобы уменьшить общее количество итераций. По умолчанию вывод не буферизуется, что означает, что для каждой небуферизованной инструкции в шаблоне выводится одна unicode-строка.

Если буферизация включена с размером буфера 5, пять элементов объединяются в новую unicode-строку. Это в основном полезно, если вы передаете большие шаблоны клиенту через WSGI, который очищается после каждой итерации.

disable_buffering()

Отключить буферизацию вывода.

dump(fp, encoding=None, errors='strict')

Выгрузить весь поток в файл или подобный файлу объект. По умолчанию записываются unicode-строки, если вы хотите закодировать перед записью, укажите encoding.

Пример использования:

Template('Hello {{ name }}!').stream(name='foo').dump('hello.html')
enable_buffering(size=5)

Включить буферизацию. Буферизовать size элементов перед их выводом.

Автоматическое экранирование

Журнал изменений

Изменено в версии 2.4.

Jinja теперь имеет поддержку автоматического экранирования. Начиная с Jinja 2.9, расширение autoescape удалено и встроено. Однако автоматическое экранирование еще не включено по умолчанию, хотя это, скорее всего, изменится в будущем. Рекомендуется настроить разумное значение по умолчанию для автоматического экранирования. Это позволяет включать и отключать автоматическое экранирование для каждого шаблона (например, HTML против текста).

jinja2.select_autoescape(enabled_extensions=('html', 'htm', 'xml'), disabled_extensions=(), default_for_string=True, default=False)

Интеллектуально устанавливает начальное значение автоматического экранирования на основе имени файла шаблона. Это рекомендуемый способ настройки автоматического экранирования, если вы не хотите писать собственную функцию.

Если вы хотите включить его для всех шаблонов, созданных из строк, или для всех шаблонов с расширениями .html и .xml:

from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(
    enabled_extensions=('html', 'xml'),
    default_for_string=True,
))

Пример конфигурации для включения его всегда, кроме случаев, когда шаблон заканчивается на .txt:

from jinja2 import Environment, select_autoescape
env = Environment(autoescape=select_autoescape(
    disabled_extensions=('txt',),
    default_for_string=True,
    default=True,
))

enabled_extensions — это итерируемый объект всех расширений, для которых должно быть включено автоматическое экранирование. Аналогично, disabled_extensions — это список всех шаблонов, для которых оно должно быть отключено. Если шаблон загружается из строки, используется значение по умолчанию из default_for_string. Если ничего не совпадает, начальное значение автоматического экранирования устанавливается в значение default.

В целях безопасности эта функция работает без учета регистра.

Журнал изменений

Новое в версии 2.9.

Вот рекомендуемая настройка, которая включает автоматическое экранирование для шаблонов, заканчивающихся на '.html', '.htm' и '.xml', и отключает его по умолчанию для всех других расширений. Вы можете использовать функцию select_autoescape() для этого:

from jinja2 import Environment, PackageLoader, select_autoescape
env = Environment(autoescape=select_autoescape(['html', 'htm', 'xml']),
                  loader=PackageLoader('mypackage'))

Функция select_autoescape() возвращает функцию, которая работает примерно так:

def autoescape(template_name):
    if template_name is None:
        return False
    if template_name.endswith(('.html', '.htm', '.xml'))

При реализации функции автоматического экранирования, убедитесь, что вы также принимаете None в качестве допустимого имени шаблона. Это будет передано при генерации шаблонов из строк. Вы всегда должны настраивать автоматическое экранирование, так как настройки по умолчанию могут измениться в будущем.

Внутри шаблонов поведение может быть временно изменено с помощью блока autoescape (см. Переопределение автоматического экранирования).

Примечания к именованию идентификаторов

Jinja использует правила именования Python. Допустимые идентификаторы могут быть любой комбинацией символов Unicode, принятых Python.

Фильтры и тесты ищутся в отдельных пространствах имен и имеют немного измененный синтаксис идентификаторов. Фильтры и тесты могут содержать точки для группировки фильтров и тестов по темам. Например, вполне допустимо добавить функцию в словарь фильтров и назвать ее to.unicode. Регулярное выражение для идентификаторов фильтров и тестов — [a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*`.

Неопределенные типы

Эти классы могут использоваться как неопределенные типы. Конструктор Environment принимает параметр undefined, который может быть одним из этих классов или пользовательским подклассом Undefined. Всякий раз, когда механизм шаблонов не может найти имя или получить доступ к атрибуту, создается и возвращается один из этих объектов. Затем разрешаются некоторые операции над неопределенными значениями, другие — нет.

Наиболее близким к обычному поведению Python является StrictUndefined, который не допускает никаких операций, кроме проверки того, является ли это неопределенным объектом.

class jinja2.Undefined

Тип по умолчанию для неопределенных значений. Этот неопределенный тип может быть выведен на печать и перебран в цикле, но любой другой доступ вызовет исключение UndefinedError:

>>> foo = Undefined(name='foo')
>>> str(foo)
''
>>> not foo
True
>>> foo + 42
Traceback (most recent call last):
  ...
jinja2.exceptions.UndefinedError: 'foo' is undefined
_undefined_hint

Либо None или строка Unicode с сообщением об ошибке для неопределенного объекта.

_undefined_obj

Либо None или объект-владелец, вызвавший создание неопределенного объекта (например, потому что атрибут не существует).

_undefined_name

Имя для неопределенной переменной/атрибута или просто None если такой информации не существует.

_undefined_exception

Исключение, которое неопределенный объект хочет вызвать. Обычно это одно из UndefinedError или SecurityError.

_fail_with_undefined_error(*args, **kwargs)

При вызове с любыми аргументами этот метод вызывает _undefined_exception с сообщением об ошибке, сгенерированным из неопределенных подсказок, хранящихся в неопределенном объекте.

class jinja2.ChainableUndefined

Неопределенное значение, допускающее цепочки вызовов, где как __getattr__, так и __getitem__ возвращают себя, а не вызывают исключение UndefinedError.

>>> foo = ChainableUndefined(name='foo')
>>> str(foo.bar['baz'])
''
>>> foo.bar['baz'] + 42
Traceback (most recent call last):
  ...
jinja2.exceptions.UndefinedError: 'foo' is undefined

Новое в версии 2.11.0.

class jinja2.DebugUndefined

Неопределенное значение, которое возвращает отладочную информацию при выводе на печать.

>>> foo = DebugUndefined(name='foo')
>>> str(foo)
'{{ foo }}'
>>> not foo
True
>>> foo + 42
Traceback (most recent call last):
  ...
jinja2.exceptions.UndefinedError: 'foo' is undefined
class jinja2.StrictUndefined

Неопределенное значение, которое вызывает ошибку при выводе на печать и итерации, а также при булевых проверках и всех видах сравнений. Другими словами: вы ничего не можете с ним сделать, кроме проверки на то, определено ли оно с помощью теста defined.

>>> foo = StrictUndefined(name='foo')
>>> str(foo)
Traceback (most recent call last):
  ...
jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> not foo
Traceback (most recent call last):
  ...
jinja2.exceptions.UndefinedError: 'foo' is undefined
>>> foo + 42
Traceback (most recent call last):
  ...
jinja2.exceptions.UndefinedError: 'foo' is undefined

Существует также функция-фабрика, которая может декорировать неопределенные объекты для реализации логирования при возникновении ошибок:

jinja2.make_logging_undefined(logger=None, base=None)

Учитывая объект-логгер, это возвращает новый класс неопределенных значений, который будет регистрировать определенные ошибки. Он будет регистрировать итерации и вывод на печать. Если логгер не указан, создается логгер по умолчанию.

Пример:

logger = logging.getLogger(__name__)
LoggingUndefined = make_logging_undefined(
    logger=logger,
    base=Undefined
)
Журнал изменений

Новое в версии 2.8.

Параметры
  • logger – используемый логгер. Если не указан, создается логгер по умолчанию.
  • base – базовый класс, к которому добавляется функциональность логирования. По умолчанию это Undefined.

Неопределенные объекты создаются путем вызова undefined.

Реализация

Undefined объекты реализованы путем переопределения специальных методов __underscore__. Например, класс Undefined по умолчанию реализует __unicode__ таким образом, что он возвращает пустую строку, однако __int__ и другие все еще вызывают исключение. Чтобы разрешить преобразование в int путем возврата 0, вы можете реализовать свой собственный:

class NullUndefined(Undefined):
    def __int__(self):
        return 0
    def __float__(self):
        return 0.0

Чтобы запретить метод, просто переопределите его и вызовите _undefined_exception. Поскольку это очень распространенный идиоматический прием в неопределенных объектах, существует вспомогательный метод _fail_with_undefined_error(), который автоматически вызывает ошибку. Вот класс, который работает как обычный Undefined, но дает сбой при итерации:

class NonIterableUndefined(Undefined):
    __iter__ = Undefined._fail_with_undefined_error

Контекст

class jinja2.runtime.Context

Контекст шаблона хранит переменные шаблона. Он хранит значения, переданные в шаблон, а также имена, которые экспортирует шаблон. Создание экземпляров не поддерживается и нецелесообразно, поскольку оно создается автоматически на различных этапах оценки шаблона и не должно создаваться вручную.

Контекст является неизменяемым. Изменения в parent не должны происходить, а изменения в vars разрешены только из сгенерированного кода шаблона. Фильтры шаблонов и глобальные функции, помеченные как contextfunction() получают активный контекст в качестве первого аргумента и могут получать доступ к контексту только для чтения.

Контекст шаблона поддерживает операции со словарями только для чтения (get, keys, values, items, iterkeys, itervalues, iteritems, __getitem__, __contains__). Кроме того, существует метод resolve(), который не завершается ошибкой KeyError, а возвращает объект Undefined для отсутствующих переменных.

parent

Словарь глобальных переменных только для чтения, которые ищет шаблон. Они могут поступать из другого Context, из Environment.globals или Template.globals или указывать на словарь, созданный путем объединения глобальных переменных с переменными, переданными в функцию рендеринга. Он не должен изменяться.

vars

Локальные переменные шаблона. Этот список содержит функции среды и контекста из области действия parent, а также локальные изменения и экспортируемые переменные из шаблона. Шаблон будет изменять этот словарь во время оценки шаблона, но фильтрам и функциям контекста запрещено его изменять.

environment

Среда, загрузившая шаблон.

exported_vars

Это множество содержит все имена, которые экспортирует шаблон. Значения для имен находятся в словаре vars. Чтобы получить копию экспортированных переменных в виде словаря, можно использовать get_exported().

name

Имя загрузки шаблона, владеющего этим контекстом.

blocks

Словарь с текущим отображением блоков в шаблоне. Ключи в этом словаре — это имена блоков, а значения — список зарегистрированных блоков. Последний элемент в каждом списке — это текущий активный блок (последний в цепочке наследования).

eval_ctx

Текущий Контекст оценки.

call(callable, *args, **kwargs)

Вызывает вызываемый объект с предоставленными аргументами и именованными аргументами, но вставляет активный контекст или среду в качестве первого аргумента, если вызываемый объект является contextfunction() или environmentfunction().

get_all()

Возвращает полный контекст в виде словаря, включая экспортированные переменные. В целях оптимизации это может не возвращать фактическую копию, поэтому будьте осторожны при его использовании.

get_exported()

Получает новый словарь с экспортированными переменными.

resolve(key)

Ищет переменную, как __getitem__ или get, но возвращает объект Undefined с именем искомого имени.

Реализация

Контекст является неизменяемым по той же причине, по которой локальные переменные фрейма Python являются неизменяемыми внутри функций. Как Jinja, так и Python не используют контекст/локальные переменные фрейма в качестве хранилища данных для переменных, а только в качестве основного источника данных.

Когда шаблон обращается к переменной, которую шаблон не определяет, Jinja ищет переменную в контексте, после чего переменная обрабатывается так, как если бы она была определена в шаблоне.

Загрузчики

Загрузчики отвечают за загрузку шаблонов из ресурса, такого как файловая система. Среда будет хранить скомпилированные модули в памяти, как sys.modules Python. В отличие от sys.modules, однако, этот кэш по умолчанию ограничен по размеру, и шаблоны автоматически перезагружаются. Все загрузчики являются подклассами BaseLoader. Если вы хотите создать свой собственный загрузчик, создайте подкласс BaseLoader и переопределите get_source.

class jinja2.BaseLoader

Базовый класс для всех загрузчиков. Создайте подкласс и переопределите get_source для реализации собственного механизма загрузки. Среда предоставляет метод get_template, который вызывает метод загрузчика load для получения объекта Template.

Очень простой пример загрузчика, который ищет шаблоны в файловой системе, может выглядеть так:

from jinja2 import BaseLoader, TemplateNotFound
from os.path import join, exists, getmtime

class MyLoader(BaseLoader):

    def __init__(self, path):
        self.path = path

    def get_source(self, environment, template):
        path = join(self.path, template)
        if not exists(path):
            raise TemplateNotFound(template)
        mtime = getmtime(path)
        with file(path) as f:
            source = f.read().decode('utf-8')
        return source, path, lambda: mtime == getmtime(path)
get_source(environment, template)

Получить исходный код шаблона, имя файла и вспомогательную функцию перезагрузки для шаблона. Ему передаются среда и имя шаблона, и он должен вернуть кортеж в форме (source, filename, uptodate) или поднять ошибку TemplateNotFound, если он не может найти шаблон.

Часть source возвращаемого кортежа должна быть исходным кодом шаблона в виде unicode-строки или ASCII-байтовой строки. Имя файла должно быть именем файла в файловой системе, если он был загружен оттуда, в противном случае None. Имя файла используется Python для трассировок, если не используется расширение загрузчика.

Последний элемент кортежа — это функция uptodate. Если включена автоматическая перезагрузка, она всегда вызывается для проверки, изменился ли шаблон. Аргументы не передаются, поэтому функция должна где-то хранить старое состояние (например, в замыкании). Если она вернет False, шаблон будет перезагружен.

load(environment, name, globals=None)

Загружает шаблон. Этот метод ищет шаблон в кэше или загружает его, вызывая get_source(). Подклассы не должны переопределять этот метод, так как загрузчики, работающие с коллекциями других загрузчиков (такие как PrefixLoader или ChoiceLoader), не будут вызывать этот метод, а get_source напрямую.

Вот список встроенных загрузчиков, предоставляемых Jinja:

class jinja2.FileSystemLoader(searchpath, encoding='utf-8', followlinks=False)

Загружает шаблоны из файловой системы. Этот загрузчик может находить шаблоны в папках файловой системы и является предпочтительным способом их загрузки.

Загрузчик принимает путь к шаблонам в виде строки или, если требуется несколько расположений, список из них, который затем просматривается в заданном порядке:

>>> loader = FileSystemLoader('/path/to/templates')
>>> loader = FileSystemLoader(['/path/to/templates', '/other/path'])

По умолчанию кодировка шаблона — 'utf-8', которую можно изменить, установив параметр encoding на другое значение.

Чтобы следовать символическим ссылкам, установите параметр followlinks в True:

>>> loader = FileSystemLoader('/path/to/templates', followlinks=True)
Журнал изменений

Изменено в версии 2.8: Добавлен параметр followlinks.

class jinja2.PackageLoader(package_name, package_path='templates', encoding='utf-8')

Загружает шаблоны из пакетов Python или яиц. Он создается с именем пакета Python и путем к шаблонам в этом пакете:

loader = PackageLoader('mypackage', 'views')

Если путь к пакету не указан, предполагается 'templates'.

По умолчанию кодировка шаблона — 'utf-8', которую можно изменить, установив параметр encoding на другое значение. Из-за природы яиц можно перезагружать шаблоны только в том случае, если пакет был загружен из файловой системы, а не из zip-файла.

class jinja2.DictLoader(mapping)

Загружает шаблон из словаря Python. Ему передается словарь unicode-строк, связанных с именами шаблонов. Этот загрузчик полезен для модульного тестирования:

>>> loader = DictLoader({'index.html': 'source here'})

Поскольку автоматическая перезагрузка редко полезна, она отключена по умолчанию.

class jinja2.FunctionLoader(load_func)

Загрузчик, которому передается функция, которая выполняет загрузку. Функция получает имя шаблона и должна возвращать либо unicode-строку с исходным кодом шаблона, либо кортеж в форме (source, filename, uptodatefunc), либо None, если шаблон не существует.

>>> def load_template(name):
...     if name == 'index.html':
...         return '...'
...
>>> loader = FunctionLoader(load_template)

uptodatefunc — это функция, которая вызывается, если включена автоматическая перезагрузка, и должна возвращать True, если шаблон по-прежнему актуален. Для получения дополнительной информации обратитесь к BaseLoader.get_source(), которая имеет такое же возвращаемое значение.

class jinja2.PrefixLoader(mapping, delimiter='/')

Загрузчик, которому передается словарь загрузчиков, где каждый загрузчик привязан к префиксу. Префикс по умолчанию отделяется от шаблона с помощью косой черты, что можно изменить, установив аргумент delimiter на другое значение:

loader = PrefixLoader({
    'app1':     PackageLoader('mypackage.app1'),
    'app2':     PackageLoader('mypackage.app2')
})

При загрузке 'app1/index.html' загружается файл из пакета app1, при загрузке 'app2/index.html' — файл из второго.

class jinja2.ChoiceLoader(loaders)

Этот загрузчик работает так же, как PrefixLoader, только без указания префикса. Если шаблон не был найден одним загрузчиком, пытается следующий.

>>> loader = ChoiceLoader([
...     FileSystemLoader('/path/to/user/templates'),
...     FileSystemLoader('/path/to/system/templates')
... ])

Это полезно, если вы хотите разрешить пользователям переопределять встроенные шаблоны из другого места.

class jinja2.ModuleLoader(path)

Этот загрузчик загружает шаблоны из предварительно скомпилированных шаблонов.

Пример использования:

>>> loader = ChoiceLoader([
...     ModuleLoader('/path/to/compiled/templates'),
...     FileSystemLoader('/path/to/templates')
... ])

Шаблоны можно предварительно скомпилировать с помощью Environment.compile_templates().

Кэш байт-кода

Jinja 2.1 и выше поддерживают внешнее кэширование байт-кода. Кэши байт-кода позволяют хранить сгенерированный байт-код в файловой системе или другом месте, чтобы избежать синтаксического анализа шаблонов при первом использовании.

Это особенно полезно, если у вас есть веб-приложение, которое инициализируется при первом запросе, и Jinja компилирует много шаблонов одновременно, что замедляет работу приложения.

Чтобы использовать кэш байт-кода, создайте его экземпляр и передайте его в Environment.

class jinja2.BytecodeCache

Чтобы реализовать собственный кэш байт-кода, вы должны создать подкласс этого класса и переопределить load_bytecode() и dump_bytecode(). Оба этих метода получают Bucket.

Очень простой кэш байт-кода, который сохраняет байт-код в файловой системе:

from os import path

class MyCache(BytecodeCache):

    def __init__(self, directory):
        self.directory = directory

    def load_bytecode(self, bucket):
        filename = path.join(self.directory, bucket.key)
        if path.exists(filename):
            with open(filename, 'rb') as f:
                bucket.load_bytecode(f)

    def dump_bytecode(self, bucket):
        filename = path.join(self.directory, bucket.key)
        with open(filename, 'wb') as f:
            bucket.write_bytecode(f)

Более продвинутая версия кэша байт-кода на основе файловой системы является частью Jinja.

clear()

Очищает кэш. Этот метод не используется Jinja, но должен быть реализован, чтобы позволить приложениям очищать кэш байт-кода, используемый определенной средой.

dump_bytecode(bucket)

Подклассы должны переопределить этот метод, чтобы записать байт-код из корзины обратно в кэш. Если это невозможно, он не должен завершаться без ошибок, а должен вызывать исключение.

load_bytecode(bucket)

Подклассы должны переопределить этот метод для загрузки байт-кода в корзину. Если они не могут найти код в кэше для корзины, он ничего не должен делать.

class jinja2.bccache.Bucket(environment, key, checksum)

Корзины используются для хранения байт-кода для одного шаблона. Он создается и инициализируется кэшем байт-кода и передается функциям загрузки.

Корзины получают назначенную внутреннюю контрольную сумму из кэша и используют ее для автоматического отклонения устаревшего материала кэша. Отдельным подклассам кэша байт-кода не нужно заботиться о недействительности кэша.

environment

Environment, создавшая корзину.

key

Уникальный ключ кэша для этой корзины

code

Байт-код, если он загружен, в противном случае None.

bytecode_from_string(string)

Загрузить байт-код из строки.

bytecode_to_string()

Возвращает байт-код в виде строки.

load_bytecode(f)

Загружает байт-код из файла или объекта, подобного файлу.

reset()

Сбрасывает корзину (разгружает байт-код).

write_bytecode(f)

Сбрасывает байт-код в переданный файл или подобный файлу объект.

Встроенные кэши байт-кода:

class jinja2.FileSystemBytecodeCache(directory=None, pattern='__jinja2_%s.cache')

Кэш байт-кода, который хранит байт-код в файловой системе. Он принимает два аргумента: каталог, где хранятся элементы кэша, и строку шаблона, которая используется для построения имени файла.

Если каталог не указан, выбирается каталог кэша по умолчанию. В Windows используется временный каталог пользователя, в UNIX-системах для пользователя создается каталог во временном каталоге системы.

Шаблон можно использовать для одновременной работы нескольких отдельных кэшей в одном каталоге. Шаблон по умолчанию — '__jinja2_%s.cache'. %s заменяется на ключ кэша.

>>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache')

Этот кэш байт-кода поддерживает очистку кэша с помощью метода clear.

class jinja2.MemcachedBytecodeCache(client, prefix='jinja2/bytecode/', timeout=None, ignore_memcache_errors=True)

Этот класс реализует кэш байт-кода, который использует кэш memcache для хранения информации. Он не навязывает конкретную библиотеку memcache (memcache от tummy или cmemcache), но будет принимать любой класс, который предоставляет минимальный необходимый интерфейс.

Библиотеки, совместимые с этим классом:

  • cachelib
  • python-memcached

(К сожалению, интерфейс кэша django несовместим, поскольку он не поддерживает хранение двоичных данных, только unicode. Однако вы можете передать базовый клиент кэша в кэш байт-кода, который доступен как django.core.cache.cache._client.)

Минимальный интерфейс для клиента, передаваемого в конструктор, выглядит так:

class MinimalClientInterface
set(key, value[, timeout])

Сохраняет байт-код в кэше. value — это строка, а timeout — время ожидания ключа. Если время ожидания не указано, предполагается время ожидания по умолчанию или отсутствие времени ожидания; если оно указано, это целое число, указывающее количество секунд, в течение которых должен существовать элемент кэша.

get(key)

Возвращает значение для ключа кэша. Если элемент не существует в кэше, возвращаемое значение должно быть None.

Другие аргументы конструктора — это префикс для всех ключей, который добавляется перед фактическим ключом кэша, и время ожидания для байт-кода в системе кэша. Мы рекомендуем большое (или неограниченное) время ожидания.

Этот кэш байт-кода не поддерживает очистку используемых элементов в кэше. Метод clear является функцией без операции.

Журнал изменений

Новое в версии 2.7: Добавлена поддержка игнорирования ошибок memcache через параметр ignore_memcache_errors.

Асинхронная поддержка

Журнал изменений

Новое в версии 2.9.

Jinja поддерживает синтаксис Python async и await. Для разработчика шаблонов эта поддержка (при включении) полностью прозрачна, шаблоны остаются точно такими же. Однако разработчики должны знать об реализации, поскольку это влияет на типы API, которые вы можете использовать.

По умолчанию асинхронная поддержка отключена. Ее включение приведет к тому, что среда будет компилировать другой код за кулисами для обработки асинхронного и синхронного кода в цикле событий asyncio. Это имеет следующие последствия:

  • Для рендеринга шаблонов требуется, чтобы цикл событий был доступен текущему потоку. asyncio.get_event_loop() должен вернуть цикл событий.
  • Скомпилированный код использует await для функций и атрибутов и использует циклы async for. Для поддержки использования как асинхронных, так и синхронных функций в этом контексте вокруг всех вызовов и доступа размещается небольшой обёртки, что добавляет накладные расходы по сравнению с чисто асинхронным кодом.
  • Синхронные методы и фильтры становятся обертками вокруг соответствующих асинхронных реализаций, когда это необходимо. Например, render вызывает async_render, а |map поддерживает асинхронные итерируемые объекты.

Объекты, ожидающие завершения, могут возвращаться из функций в шаблонах, и любой вызов функции в шаблоне будет автоматически ожидать результат. await, который вы обычно добавляете в Python, подразумевается. Например, вы можете предоставить метод, который асинхронно загружает данные из базы данных, и с точки зрения разработчика шаблонов его можно вызывать как любую другую функцию.

Политики

Начиная с Jinja 2.9, политики можно настраивать в среде, что может немного повлиять на поведение фильтров и других конструкций шаблонов. Их можно настроить с помощью атрибута policies.

Пример:

env.policies['urlize.rel'] = 'nofollow noopener'
compiler.ascii_str:

Это булево значение управляет в Python 2, должен ли Jinja хранить литералы только ASCII как байтовые строки вместо строк unicode. Раньше это всегда было включено для версий Jinja ниже 2.9, а теперь это можно изменить. Традиционно это делалось таким образом, поскольку некоторые API в Python 2 сильно выходили из строя для строк unicode (например, API datetime strftime). Однако теперь иногда верно обратное (например, str.format). Если это установлено в False, то все строки хранятся как unicode внутри.

truncate.leeway:

Настраивает значение по умолчанию для допустимого отклонения для фильтра truncate. Допустимое отклонение было введено в версии 2.9, но для восстановления совместимости со старыми шаблонами его можно настроить на 0, чтобы вернуть старое поведение. Значение по умолчанию — 5.

urlize.rel:

Строка, определяющая элементы для атрибута rel генерируемых ссылок с фильтром urlize. Эти элементы всегда добавляются. Значение по умолчанию — noopener.

urlize.target:

Целевая метка по умолчанию, которая используется для ссылок из фильтра urlize, если другая целевая метка не определена вызовом явно.

json.dumps_function:

Если это установлено в значение, отличное от None, то фильтр tojson будет использовать эту функцию вместо функции по умолчанию. Обратите внимание, что эта функция должна принимать произвольные дополнительные аргументы, которые могут быть переданы в будущем из фильтра. В настоящее время единственным аргументом, который может быть передан, является indent. Функция дампа по умолчанию — json.dumps.

json.dumps_kwargs:

Именованные аргументы для передачи в функцию дампа. Значение по умолчанию — {'sort_keys': True}.

ext.i18n.trimmed:

Если это установлено в True, блоки {% trans %} расширения i18n Extension всегда будут унифицировать разрывы строк и окружающие пробелы, как если бы использовался модификатор trimmed.

Утилиты

Эти вспомогательные функции и классы полезны, если вы добавляете пользовательские фильтры или функции в среду Jinja.

jinja2.environmentfilter(f)

Декоратор для маркировки фильтров, зависящих от среды. Текущая Environment передается в фильтр в качестве первого аргумента.

jinja2.contextfilter(f)

Декоратор для маркировки фильтров, зависящих от контекста. Текущий Context будет передан в качестве первого аргумента.

jinja2.evalcontextfilter(f)

Декоратор для маркировки фильтров, зависящих от контекста вычислений. Объект контекста вычислений передается в качестве первого аргумента. Для получения дополнительной информации о контексте вычислений см. Контекст вычислений.

Журнал изменений

Новое в версии 2.4.

jinja2.environmentfunction(f)

Этот декоратор можно использовать для маркировки функции или метода как вызываемого из среды. Этот декоратор работает точно так же, как декоратор contextfunction(), за исключением того, что первый аргумент — это активная Environment, а не контекст.

jinja2.contextfunction(f)

Этот декоратор можно использовать для маркировки функции или метода как вызываемого из контекста. Вызываемый из контекста получает активный Context в качестве первого аргумента при вызове из шаблона. Это полезно, если функция хочет получить доступ к контексту или функциям, предоставленным в объекте контекста. Например, функция, которая возвращает отсортированный список переменных шаблона, которые экспортирует текущий шаблон, может выглядеть так:

@contextfunction
def get_exported_names(context):
    return sorted(context.exported_vars)
jinja2.evalcontextfunction(f)

Этот декоратор можно использовать для маркировки функции или метода как вызываемого из контекста вычислений. Это похоже на contextfunction(), но вместо передачи контекста передается объект контекста вычислений. Для получения дополнительной информации о контексте вычислений см. Контекст вычислений.

Журнал изменений

Новое в версии 2.4.

jinja2.escape(s)

Преобразует символы &, <, >, ' и " в строке s в безопасные для HTML последовательности. Используйте это, если вам нужно отобразить текст, который может содержать такие символы в HTML. Эта функция не будет экранировать объекты, которые имеют HTML-представление, например, уже экранированные данные.

Возвращаемое значение — строка Markup.

jinja2.clear_caches()

Jinja хранит внутренние кэши для сред и лексеры. Они используются для того, чтобы Jinja не приходилось постоянно создавать среды и лексеры. Обычно вам не нужно беспокоиться об этом, но если вы измеряете потребление памяти, вы можете очистить кэши.

jinja2.is_undefined(obj)

Проверить, является ли переданный объект неопределенным. Это не делает ничего больше, чем выполняет проверку экземпляра для Undefined, но выглядит лучше. Это можно использовать для пользовательских фильтров или тестов, которые хотят реагировать на неопределенные переменные. Например, пользовательский фильтр по умолчанию может выглядеть так:

def default(var, default=''):
    if is_undefined(var):
        return default
    return var
class jinja2.Markup([string])

Строка, готовая к безопасному вставлению в HTML или XML документ, либо потому что она была экранирована, либо потому что она была помечена как безопасная.

Передача объекта в конструктор преобразует его в текст и оборачивает его, помечая его как безопасный без экранирования. Чтобы экранировать текст, используйте метод класса escape() вместо этого.

>>> Markup('Hello, <em>World</em>!')
Markup('Hello, <em>World</em>!')
>>> Markup(42)
Markup('42')
>>> Markup.escape('Hello, <em>World</em>!')
Markup('Hello &lt;em&gt;World&lt;/em&gt;!')

Это реализует интерфейс __html__(), который используется некоторыми фреймворками. Передача объекта, который реализует __html__(), обернёт вывод этого метода, помечая его как безопасный.

>>> class Foo:
...     def __html__(self):
...         return '<a href="/foo">foo</a>'
...
>>> Markup(Foo())
Markup('<a href="/foo">foo</a>')

Это подкласс текстового типа (str в Python 3, unicode в Python 2). Он имеет те же методы, что и этот тип, но все методы экранируют свои аргументы и возвращают экземпляр Markup.

>>> Markup('<em>%s</em>') % 'foo & bar'
Markup('<em>foo &amp; bar</em>')
>>> Markup('<em>Hello</em> ') + '<foo>'
Markup('<em>Hello</em> &lt;foo&gt;')
classmethod escape(s)

Экранировать строку. Вызывает escape() и гарантирует, что для подклассов возвращается правильный тип.

striptags()

unescape() разметку, удалить теги и нормализовать пробелы до одиночных пробелов.

>>> Markup('Main &raquo;        <em>About</em>').striptags()
'Main » About'
unescape()

Преобразовать экранированную разметку обратно в текстовую строку. Это заменяет HTML-сущности символами, которые они представляют.

>>> Markup('Main &raquo; <em>About</em>').unescape()
'Main » <em>About</em>'

Примечание

Класс Jinja Markup совместим, по крайней мере, с Pylons и Genshi. Ожидается, что больше шаблонизаторов и фреймворков скоро подхватят концепцию __html__.

Исключения

exception jinja2.TemplateError(message=None)

Базовый класс для всех ошибок шаблонов.

exception jinja2.UndefinedError(message=None)

Возбуждается, если шаблон пытается выполнить операцию над Undefined.

exception jinja2.TemplateNotFound(name, message=None)

Возбуждается, если шаблон не существует.

Изменено в версии 2.11: Если заданное имя является Undefined и сообщение не было предоставлено, возбуждается исключение UndefinedError.

exception jinja2.TemplatesNotFound(names=(), message=None)

Как TemplateNotFound, но возбуждается, если выбрано несколько шаблонов. Это подкласс исключения TemplateNotFound, поэтому перехват базового исключения перехватит оба.

Изменено в версии 2.11: Если имя в списке имён является Undefined, отображается сообщение о том, что оно не определено, а не пустая строка.

Журнал изменений

Новое в версии 2.2.

exception jinja2.TemplateSyntaxError(message, lineno, name=None, filename=None)

Возбуждается, чтобы сообщить пользователю о проблеме с шаблоном.

message

Сообщение об ошибке в виде байтовой строки utf-8.

lineno

Номер строки, где произошла ошибка

name

Имя загрузки для шаблона в виде юникодной строки.

filename

Имя файла, загрузившего шаблон, в виде байтовой строки в кодировке файловой системы (скорее всего utf-8 или mbcs в системах Windows).

Причина, по которой имя файла и сообщение об ошибке являются байтовыми строками, а не юникодными строками, заключается в том, что Python 2.x не использует юникод для исключений и трассировок, а также компилятора. Это изменится с Python 3.

exception jinja2.TemplateRuntimeError(message=None)

Общая ошибка времени выполнения в шаблонизаторе. В некоторых ситуациях Jinja может возбудить это исключение.

exception jinja2.TemplateAssertionError(message, lineno, name=None, filename=None)

Как ошибка синтаксиса шаблона, но охватывает случаи, когда что-то в шаблоне вызвало ошибку во время компиляции, которая не обязательно была вызвана ошибкой синтаксиса. Однако это прямой подкласс TemplateSyntaxError и имеет те же атрибуты.

Пользовательские фильтры

Пользовательские фильтры — это обычные функции Python, которые принимают левую часть фильтра в качестве первого аргумента и аргументы, переданные фильтру, в качестве дополнительных аргументов или именованных аргументов.

Например, в фильтре {{ 42|myfilter(23) }} функция будет вызвана с myfilter(42, 23). Вот, например, простой фильтр, который можно применить к объектам datetime для их форматирования:

def datetimeformat(value, format='%H:%M / %d-%m-%Y'):
    return value.strftime(format)

Вы можете зарегистрировать его в среде шаблонов, обновив словарь filters в среде:

environment.filters['datetimeformat'] = datetimeformat

Внутри шаблона его можно использовать следующим образом:

written on: {{ article.pub_date|datetimeformat }}
publication date: {{ article.pub_date|datetimeformat('%d-%m-%Y') }}

Фильтры также могут получать доступ к текущему контексту шаблона или среде. Это полезно, если фильтр хочет вернуть неопределенное значение или проверить текущую настройку autoescape. Для этой цели существуют три декоратора: environmentfilter(), contextfilter() и evalcontextfilter().

Вот небольшой пример фильтра, который разбивает текст на HTML-разрывы строк и абзацы и помечает возвращаемое значение как безопасную HTML-строку, если включено автоматическое экранирование:

import re
from jinja2 import evalcontextfilter, Markup, escape

_paragraph_re = re.compile(r'(?:\r\n|\r(?!\n)|\n){2,}')

@evalcontextfilter
def nl2br(eval_ctx, value):
    result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', Markup('<br>\n'))
                          for p in _paragraph_re.split(escape(value)))
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

Контекстные фильтры работают так же, только первый аргумент — это текущий активный Context, а не среда.

Контекст вычислений

Контекст вычислений (сокращенно контекст вычислений или контекст вычислений) — это новый объект, введенный в Jinja 2.4, который позволяет активировать и деактивировать скомпилированные функции во время выполнения.

В настоящее время он используется только для включения и выключения автоматического экранирования, но может также использоваться для расширений.

В предыдущих версиях Jinja фильтры и функции помечались как вызываемые из среды для проверки состояния автоэкранирования из среды. В новых версиях рекомендуется вместо этого проверять настройку из контекста вычислений.

Предыдущие версии:

@environmentfilter
def filter(env, value):
    result = do_something(value)
    if env.autoescape:
        result = Markup(result)
    return result

В новых версиях вы можете либо использовать contextfilter() и получить доступ к контексту вычислений из фактического контекста, либо использовать evalcontextfilter(), который напрямую передает контекст вычислений функции:

@contextfilter
def filter(context, value):
    result = do_something(value)
    if context.eval_ctx.autoescape:
        result = Markup(result)
    return result

@evalcontextfilter
def filter(eval_ctx, value):
    result = do_something(value)
    if eval_ctx.autoescape:
        result = Markup(result)
    return result

Контекст вычислений не должен изменяться во время выполнения. Изменения должны происходить только с помощью nodes.EvalContextModifier и nodes.ScopedEvalContextModifier из расширения, а не с самим объектом контекста вычислений.

class jinja2.nodes.EvalContext(environment, template_name=None)

Содержит информацию о времени вычисления. Пользовательские атрибуты могут быть прикреплены к нему в расширениях.

autoescape

True или False, в зависимости от того, активно ли автоматическое экранирование или нет.

volatile

True, если компилятор не может вычислить некоторые выражения во время компиляции. Во время выполнения это всегда должно быть False.

Пользовательские тесты

Тесты работают как фильтры, за исключением того, что у теста нет возможности получить доступ к среде или контексту, и их нельзя объединять. Возвращаемое значение теста должно быть True или False. Цель теста — дать разработчикам шаблонов возможность выполнять проверки типов и соответствия.

Вот простой тест, который проверяет, является ли переменная простым числом:

import math

def is_prime(n):
    if n == 2:
        return True
    for i in range(2, int(math.ceil(math.sqrt(n))) + 1):
        if n % i == 0:
            return False
    return True

Вы можете зарегистрировать его в среде шаблонов, обновив словарь tests в среде:

environment.tests['prime'] = is_prime

Разработчик шаблонов может затем использовать тест следующим образом:

{% if 42 is prime %}
    42 is a prime number
{% else %}
    42 is not a prime number
{% endif %}

Глобальное пространство имен

Переменные, хранящиеся в словаре Environment.globals, являются специальными, поскольку они также доступны для импортированных шаблонов, даже если они импортируются без контекста. Это место, куда вы можете поместить переменные и функции, которые должны быть доступны постоянно. Кроме того, существуют Template.globals, которые представляют собой переменные, доступные для определенного шаблона, доступные для всех вызовов render().

Низкоуровневый API

Низкоуровневый API предоставляет функциональность, которая может быть полезна для понимания некоторых деталей реализации, целей отладки или расширенных методов расширения. Если вы точно не знаете, что делаете, мы не рекомендуем использовать что-либо из этого.

Environment.lex(source, name=None, filename=None)

Лексический анализ заданного исходного кода и возврат генератора, который выдает токены в виде кортежей формы (lineno, token_type, value). Это может быть полезно для разработки расширений и отладки шаблонов.

Это не выполняет предварительную обработку. Если вы хотите, чтобы предварительная обработка расширений применялась, вам необходимо отфильтровать источник через метод preprocess().

Environment.parse(source, name=None, filename=None)

Разбор исходного кода и возврат абстрактного синтаксического дерева. Это дерево узлов используется компилятором для преобразования шаблона в исполняемый исходный код или байт-код. Это полезно для отладки или извлечения информации из шаблонов.

Если вы разрабатываете расширения Jinja, это дает вам хорошее представление о генерируемом дереве узлов.

Environment.preprocess(source, name=None, filename=None)

Предварительная обработка источника со всеми расширениями. Это автоматически вызывается для всех методов синтаксического анализа и компиляции, но не для lex(), потому что там обычно вам нужен только фактически токенизированный исходный код.

Template.new_context(vars=None, shared=False, locals=None)

Создает новый Context для этого шаблона. Предоставленные переменные будут переданы в шаблон. По умолчанию глобальные переменные добавляются в контекст. Если shared установлен в True, данные передаются в контекст как есть без добавления глобальных переменных.

locals может быть словарем локальных переменных для внутреннего использования.

Template.root_render_func(context)

Это функция низкоуровневого рендеринга. Ей передается Context, который должен быть создан с помощью new_context() того же шаблона или совместимого шаблона. Эта функция рендеринга генерируется компилятором из кода шаблона и возвращает генератор, который выдает строки Unicode.

Если происходит исключение в коде шаблона, механизм шаблонов не будет переписывать исключение, а передаст исходное. По сути, эта функция должна вызываться только изнутри вызова render() / generate() / stream().

Template.blocks

Словарь функций рендеринга блоков. Каждая из этих функций работает точно так же, как root_render_func() с теми же ограничениями.

Template.is_up_to_date

Этот атрибут имеет значение False, если доступна более новая версия шаблона, иначе True.

Примечание

Низкоуровневый API является нестабильным. В будущих версиях Jinja будут предприняты попытки не изменять его несовместимым образом, но изменения в ядре Jinja могут проявиться. Например, если Jinja вводит новый узел AST в более поздних версиях, который может возвращаться методом parse().

Мета-API

Журнал изменений

Новое в версии 2.2.

Мета-API возвращает некоторую информацию об абстрактных синтаксических деревьях, которая может помочь приложениям реализовывать более продвинутые концепции шаблонов. Все функции мета-API работают с абстрактным синтаксическим деревом, возвращаемым методом Environment.parse().

jinja2.meta.find_undeclared_variables(ast)

Возвращает множество всех переменных в AST, которые будут извлекаться из контекста во время выполнения. Поскольку во время компиляции неизвестно, какие переменные будут использоваться в зависимости от пути выполнения, возвращаются все переменные.

>>> from jinja2 import Environment, meta
>>> env = Environment()
>>> ast = env.parse('{% set foo = 42 %}{{ bar + foo }}')
>>> meta.find_undeclared_variables(ast) == set(['bar'])
True

Реализация

Внутренне генератор кода используется для поиска необъявленных переменных. Это полезно знать, потому что генератор кода может вызывать TemplateAssertionError во время компиляции, и фактически эта функция также может вызывать это исключение.

jinja2.meta.find_referenced_templates(ast)

Находит все ссылающиеся шаблоны из AST. Это вернет итератор по всем жестко закодированным расширениям, включениям и импортам шаблонов. Если используется динамическое наследование или включение, будет выдан None.

>>> from jinja2 import Environment, meta
>>> env = Environment()
>>> ast = env.parse('{% extends "layout.html" %}{% include helper %}')
>>> list(meta.find_referenced_templates(ast))
['layout.html', None]

Эта функция полезна для отслеживания зависимостей. Например, если вы хотите перестроить части веб-сайта после изменения шаблона макета.

© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://jinja.palletsprojects.com/en/2.11.x/api/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API