Конструкции include и import

Часто при создании сайтов страницу делят, как минимум на три части:

заголовок, контент, футер

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

{% include <путь к файлу шаблона> %}

Например, сделать так. Разобьем страницу main.htm на три блока:

- заголовок (header.htm):

<!DOCTYPE html>
<html>
<head>
         <base href="https://proproprogs.ru/">
         <title>Про программирование</title>
</head>
<body>

- футер (footer.htm):

</body>
</html>

- страницу (page.htm)

{% include 'header.htm' %}
Содержимое страницы
{% include 'footer.htm' %}

Теперь, в программе можно просто загрузить шаблон page.htm и получить целиком собранную HTML-страницу:

file_loader = FileSystemLoader('templates')
env = Environment(loader=file_loader)
 
tm = env.get_template('page.htm')
msg = tm.render()
 
print(msg)

Блок include можно записывать с дополнительными параметрами:

{% include "header.html" ignore missing %}

В этом случае отсутствие шаблона не будет приводить к появлению исключения TemplateNotFound. Например, записав вот такую строчку:

{% include 'header.html' ignore missing %}

получим шаблон без 'header.html', т.к. такой файл отсутствует в текущем каталоге.

Вернем запись:

{% include 'header.htm' ignore missing %}

а в самом файле 'header.htm' пропишем шаблон для домена и заголовка страницы:

<!DOCTYPE html>
<html>
<head>
         <meta charset="UTF-8">
         <base href="{{domain}}">
         <title>{{title}}</title>
</head>
<body>

Теперь, вызывая шаблон 'page.htm' можем передавать ему домен и заголовок для каждой страницы:

tm = env.get_template('page.htm')
msg = tm.render(domain='http://proproprogs.ru', title="Про Jinja")

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

Если в блоке include требуется подключить сразу несколько файлов, то их следует указать в виде списка:

{% include ['page1.htm', 'page2.htm'] ignore missing %}

Конструкция import

Модуль Jinja позволяет не только включать отдельные файлы в общий шаблон, но и импортировать их. Отличие в том, что при импорте шаблон не добавляется, но можно использовать его отдельные конструкции. Например, представим себе, что в HTML-документе могут присутствовать диалоговые окна. Их реализацию опишем в виде макроса, который расположим в отдельном файле dialogs.htm:

{% macro dialog_1(title, msg='') -%}
<div class="dialog">
<p class="title">{{title}}</p>
<p class="message">{{msg}}</p>
<input type="button" value="Закрыть"></p>
</div>
{%- endmacro %}

И, затем, импортируем его в основном шаблоне page.htm:

{% include 'header.htm' ignore missing %}
{% import 'dialogs.htm' as dlg %}
Содержимое страницы
{{ dlg.dialog_1('Внимание', 'Это тестовый диалог') }}
{% include 'footer.htm' %}

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

Или же, воспользоваться такой конструкцией:

{% include 'header.htm' ignore missing  %}
{% from 'dialogs.htm' import dialog_1 as dlg %}
Содержимое страницы
{{ dlg('Внимание', 'Это тестовый диалог') }}
{% include 'footer.htm' %}

Тогда обращение к макросу будет происходить по имени dlg.