Загрузчики: FileSystemLoader, PackageLoader, FunctionLoader и другие

Рассматриваемые шаблоны на предыдущих занятиях были записаны в виде многострочного текста, но на практике, шаблоны, как правило, хранятся в отдельных текстовых файлах и загружаются по мере необходимости. Для этого в Jinja реализован класс Enviroment (окружение), который, наверное, представляет собой некий центральный объект, через который и происходит основная работа с API данного пакета. Я здесь не буду приводить подробное описание параметров этого класса, так как это сугубо справочная информация и ее можно самостоятельно изучить вот по этой ссылке:

https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.Environment

Вместо этого мы рассмотрим примеры использования этого объекта. Итак, предположим, что все наши шаблоны хранятся в подкаталоге

templates

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

<!DOCTYPE html>
<html>
<head>
         <base href="https://proproprogs.ru/">
         <title>Про программирование</title>
</head>
<body>
 
<ul>
{% for u in users -%}
    <li>{{u.name}} 
{% endfor -%}
</ul>
 
</body>
</html>

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

from jinja2 import Environment, FileSystemLoader
 
persons = [
    {"name": "Алексей", "old": 18, "weight": 78.5},
    {"name": "Николай", "old": 28, "weight": 82.3},
    {"name": "Иван", "old": 33, "weight": 94.0}
]
 
file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
 
tm = env.get_template('main.htm')
msg = tm.render(users = persons)
 
print(msg)

Мы здесь вначале импортируем модули Environment и FileSystemLoader, затем, создаем файловый загрузчик, который будет брать шаблоны из подкаталога 'templates'. Далее, создается объект Environment, у которого параметр loader ссылается на файловый загрузчик. В результате, мы можем загружать и обрабатывать любые шаблоны, находящиеся в подкаталоге 'templates'. С помощью метода get_template загружается файл 'main.htm' и возвращается объект шаблона (Template) с его содержимым. В конце вызывается метод render для обработки шаблона и формирования строки HTML-документа на основе списка persons.

Обратите внимание, по умолчанию Python работает со строками в формате Юникода, поэтому для корректного представления кириллицы необходимо сохранять текстовые файлы в формате UTF8.

Помимо FileSystemLoader, который отвечает за загрузку шаблонов непосредственно из файловой системы, в Jinja есть еще несколько предопределенных загрузчиков:

  • PackageLoader – для загрузки шаблонов из пакета;
  • DictLoader – для загрузки шаблонов из словаря;
  • FunctionLoader – для загрузки на основе функции;
  • PrefixLoader – загрузчик, использующий словарь для построения подкаталогов;
  • ChoiceLoader – загрузчик, содержащий список других загрузчиков (если один не сработает, выбирается следующий);
  • ModuleLoader – загрузчик для скомпилированных шаблонов.

Например, FunctionLoader можно реализовать так. Определим некую функцию, которая будет возвращать шаблон:

def loadTpl(path):
    if path == "index":
        return '''Имя {{u.name}}, возраст {{u.old}}'''
    else:
        return '''Данные: {{u}}'''

И, затем, реализуем загрузчик на ее основе:

file_loader = FunctionLoader(loadTpl)
env = Environment(loader=file_loader)
 
tm = env.get_template('index')
msg = tm.render(u = persons[0])

Так как берется шаблон 'index', то именно это значение будет принимать параметр path и функция возвратит первый шаблон. Если указать любое другое значение, то получим второй шаблон.

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

https://jinja.palletsprojects.com/en/2.11.x/api/#jinja2.FileSystemLoader