Сообщить об ошибке.

Класс Environment() модуля jinja2 в Python

Среда окружения движка шаблонов jinja2

Синтаксис:

import jinja2

loader = jinja2.FileSystemLoader('temp')
# инициализация среды окружения
env = jinja2.Environment(loader=loader, trim_blocks=True)
tpl = env.get_template('main.txt')
...

Возвращаемое значение:

Описание:

Класс Environment() - среда окружения модуля jinja2 и является основным компонентом движка шаблонов.

Среда окружения Environment содержит важные общие переменные, такие как конфигурация, фильтры, глобальные переменные и другие.

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

Возможные ключевые аргументы конструктора класса Environment():

  • block_start_string: Строка, отмечающая начало блока. По умолчанию '{%'.
  • block_end_string: Строка, отмечающая конец блока. По умолчанию '%}'.
  • variable_start_string: Строка, отмечающая начало инструкции печати. По умолчанию '{{'.
  • variable_end_string: Строка, отмечающая конец инструкции печати. По умолчанию '}}'.
  • comment_start_string: Строка, отмечающая начало комментария. По умолчанию '{#'.
  • comment_end_string: Строка, отмечающая конец комментария. По умолчанию '#}'.
  • line_statement_prefix: Если задано, то эта строка будет использоваться в качестве префикса для операторов на основе строк. Подробнее смотрите "Общий синтаксис шаблонов Jinja" подраздел "Использование строчных операторов в шаблонах".
  • line_comment_prefix:Если задано, то эта строка будет использоваться в качестве префикса для комментариев на основе строк. Подробнее смотрите "Общий синтаксис шаблонов Jinja" подраздел "Использование строчных операторов в шаблонах".
  • trim_blocks: Если установлено значение True, то удаляется пустая строка после удаления блока (блок, а не тег переменной!). По умолчанию False.
  • lstrip_blocks: Если задано значение True, то начальные пробелы и табуляция удаляются от начала строки до блока. По умолчанию установлено значение False.
  • newline_sequence: Последовательность, с которой начинается новая строка. Должно быть, один из "\r", "\n" или "\r\n". Значение по умолчанию - "\n", что является нормальным для систем Linux и OS X, а также веб-приложений.
  • keep_trailing_newline: Сохраняет конечный символ новой строку при отрисовке шаблонов. Значение по умолчанию равно False, это приводит к удалению одной новой строки из конца шаблона, если она присутствует.
  • extensions: Список расширений Jinja для использования. Это могут быть либо пути импорта в виде строк, либо классы расширений.
  • optimized: Должен ли быть включен оптимизатор? Значение по умолчанию равно True.
  • undefined: Undefined или его подкласс, используемый для представления неопределенных значений в шаблоне.
  • finalize: Вызываемый объект, который можно использовать для обработки результата выражения переменной перед его выводом. Например, здесь можно неявно преобразовать None в пустую строку.
  • autoescape: Если установлено значение True, то функция авто экранирования XML/HTML включена по умолчанию. Дополнительные сведения об авто экранировании смотрите класс jinja2.Markup.
  • loader: Загрузчик шаблонов для этой среды. Дополнительные сведения смотрите в разделе "Загрузчики шаблонов"
  • cache_size: Размер кэша. По умолчанию это значение равно 400, что означает, что если загружено более 400 шаблонов, загрузчик очистит наименее использованный шаблон. Если размер кэша равен 0, шаблоны постоянно перекомпилируются, если размер кэша равен -1, кэш не будет очищен.
  • auto_reload: Некоторые загрузчики загружают шаблоны из мест, где источники шаблонов могут изменяться (например, файловая система или база данных). Если auto_reload имеет значение True (по умолчанию), то каждый раз, когда запрашивается шаблон, загрузчик проверяет, изменился ли источник, и, если да, то он перезагружает шаблон. Для повышения производительности можно отключить такое поведение.
  • bytecode_cache: Объект кэша байт-кода. Если задан, то этот объект обеспечит кэш для внутреннего байт-кода Jinja, так что шаблоны не перекомпилируются, если они не изменялись.
  • enable_async: Если установлено значение True, это позволяет выполнять асинхронные шаблоны, что позволяет использовать преимущества новых функций Python 3.6 или более поздней версии.

Атрибуты и методы объекта Environment.


Environment.shared:

Для всех общих сред, атрибут Environment.shared имеет значение True, в противном случае - False.

Если шаблон был создан с помощью конструктора jinja2.Template(), то среда создается автоматически. Эти среды создаются как общие среды, что означает, что несколько шаблонов могут иметь одну и ту же анонимную среду.

Environment.sandboxed:

Если среда изолирована, то атрибут Environment.sandboxed имеет значение True.

Environment.filters:

Атрибут Environment.filters - это словарь фильтров для этой среды. Пока не загружен шаблон, можно безопасно добавлять новые фильтры или удалять старые. Как создавать пользовательские фильтры, смотрите материал "Пользовательские фильтры. Допустимые имена фильтров смотрите в примечании к идентификаторам в обзорном материале к модулю jinja2.

Environment.tests:

Атрибут Environment.tests - это словарь тестовых функций для этой среды. Пока шаблон не был загружен, можно безопасно изменить этот словарь. Как создавать пользовательские тесты смотрите материал "Пользовательские тесты". Допустимые имена тестов смотрите в примечании к идентификаторам в обзорном материале к модулю jinja2.

Environment.globals:

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

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

Environment.policies:

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

Environment.code_generator_class:

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

Environment.context_class:

Атрибут Environment.context_class это контекст, используемый для шаблонов. Этот атрибут не должен быть изменен в большинстве случаев, если только не требуется изменить внутренние параметры обработки переменных шаблона.

Environment.overlay([options]):

Метод Environment.overlay() создает и возвращает новую среду наложения Environment, которая разделяет все данные с текущей средой, за исключением кеша и переопределенных атрибутов. Для наложенной среды нельзя удалить расширения. Наложенная среда автоматически получает все расширения среды, с которой она связана, а также необязательные дополнительные расширения.

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

  • options - это ключевые аргументы конструктора, те же самые, которые принимает класс jinja.Environment().

Environment.undefined([hint, obj, name, exc]):

Метод Environment.undefined() создает новый неопределенный объект для имени name. Это полезно для фильтров или функций, которые могут возвращать неопределенные объекты для некоторых операций. Все параметры, кроме hint, должны быть предоставлены как ключевые аргументы для лучшей читаемости. Аргумент hint используется как сообщение об ошибке для исключения exc, если оно предоставлено, в противном случае сообщение об ошибке будет автоматически сгенерировано из объекта obj и имени name. Исключение, представленное как exc, возникает, если со сгенерированным неопределенным объектом делается что-то, что не позволяет неопределенный объект. Исключение по умолчанию - jinja2.UndefinedError. Если указан аргумент hint, то name можно не указывать.

Самый распространенный способ создать неопределенный объект - указать только имя:

return environment.undefined(name='some_name')

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

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

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

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

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

Environment.add_extension(extension):

Метод Environment.add_extension() добавляет расширение после создания среды.

Environment.compile_expression(source, undefined_to_none=True):

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

Метод полезен, если приложения хотят использовать те же правила, что и модуль 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

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

Метод Environment.compile_templates() находит все шаблоны, которые может найти загрузчик, компилирует их и сохраняет в целевой папке. Если аргумент zip имеет значение None, то вместо zip-файла, шаблоны будут храниться в каталоге. По умолчанию используется алгоритм сжатия 'deflate'. Для аргумента zip можно также установить значение 'stored'.

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

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

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

Environment.extend(**attributes):

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

Environment.from_string(source, globals=None, template_class=None):

Метод Environment.from_string() загружает шаблон из строки. Метод анализирует данный источник и возвращает объект Template.

Environment.get_or_select_template(template_name_or_list, parent=None, globals=None):

Метод Environment.get_or_select_template() выполняет проверку типов и отправляет в Environment.select_template(), если задан аргумент template_name_or_list, в противном случае отправит в Environment.get_template().

Environment.get_template(name, parent=None, globals=None):

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

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

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

Environment.join_path(template, parent):

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

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

Environment.list_templates(extensions=None, filter_func=None):

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

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

Если загрузчик не поддерживает метод .list_templates(), то возникает ошибка TypeError.

Environment.select_template(names, parent=None, globals=None):

Метод Environment.select_template() работает как [Environment.get_template()](#Environment.get_template), но пробует несколько шаблонов, прежде чем потерпит неудачу. Если он не может найти ни один из шаблонов, то вызовет исключениеjinja2.TemplatesNotFound`.

Изменено в Jinja 2.11: если для names установлено значение Undefined, то возникает jinja2.UndefinedError. Если шаблоны не найдены, а names=Undefined, то сообщение будет более полезным.

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

Метод Environment.lex() разбирает заданный исходный код source и возвращает генератор, который выдает токены в виде кортежей в форме (lineo, token_type, value). Это может быть полезно для разработки расширений и отладки шаблонов.

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

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

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

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

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

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


Пример инициализации среды окружения движка шаблонов jinja2.

Сохраним шаблон, представленный ниже, в директорию ~/temp/main.txt.

{# файл шаблона ~/temp/main.txt #}
{{ title }}
{# Добавим условие #}
{% if title %}
{# Если существует переменная `title`, то будем ее подчеркивать #}
{{ '-' * title|length }}
{% endif %}
{# Цикл по пользователям #}
{% for n, user in enumerate(users, 1) %}
{{ n }}. {{ user.name }} - должность: {{ user.status }}, оклад: ${{ user.salary }}
{% endfor %}

Ниже представлен основной код программы, которая работает с сохраненным шаблоном main.txt. Для понимания того, что происходит, код снабжен подробными комментариями.

import jinja2
 
# Определяем класс загрузчика шаблонов из файловой системы
# (`temp` - папка где лежит сохраненный шаблон 'main.txt')
loader = jinja2.FileSystemLoader('temp')
# Определяем переменную среду, 
# в которую передаем загрузчик
env = jinja2.Environment(loader=loader, trim_blocks=True)

# данные для шаблона
content = {}
content['title'] = 'Итерация по пользователям'
content['users'] = []
content['users'].append({'name': 'Маша', 'status': 'Менеджер', 'salary': 1500}) 
content['users'].append({'name': 'Света', 'status': 'Дизайнер', 'salary': 1000}) 
content['users'].append({'name': 'Игорь', 'status': 'Программист', 'salary': 2000}) 
# В словаре передаем в шаблон функцию Python
content['enumerate'] = enumerate

# загружаем шаблон 'main.txt'
tpl = env.get_template('main.txt')
# рендерим шаблон в переменную `result`
result = tpl.render(content)
# Сохраним получившийся текст
with open('result.txt', 'w') as fp: 
    fp.write(result)

# Прочитаем записанный файл
with open('result.txt', 'r') as fp: 
    print(fp.read())

# Итерация по пользователям
# -------------------------
# 1. Маша - должность: Менеджер, оклад: $1500
# 2. Света - должность: Дизайнер, оклад: $1000
# 3. Игорь - должность: Программист, оклад: $2000