Шаблоны Django. Наследование.

Информация полезная для меня (занесла в заметки), думаю пригодится и для других, поэтому должна быть под рукой
  • структура шаблонов Django
  • наследование шаблонов
  • пример


Структура шаблонов Django


Управляющими элементами шаблонов Django являются переменные, фильтры и теги.
При рендеринге шаблона переменные заменяются на свое значение, вычисленное в контексте вызова. Синтаксис - двойные фигурные скобки - например: {{ title }}.

Фильтры служат для простых преобразований переменных. Синтаксис - переменная|имя_фильтра:"параметры". Фильтр может встречаться как в переменных, так и в качестве параметра тега. Например: {{ title|lowercase }}.

При рендеринге шаблона теги, грубо говоря, заменяются на результаты работы ассоциированной с этим тегом функции на питоне. Синтаксис: {% тег параметры %}, например: {% url blog_article slug=article.slug %}.

Кроме того, есть три специальных тега: include, block и extend. Тег include подставляет запрошенный шаблон (отрендеренный в текущем контексте).

Наследование шаблонов

 

Основная фишка шаблонов Django - наследование. Шаблон может расширять (уточнять) поведение родительского шаблона.

Любой участок шаблона может быть обернут в блочный тег (естественно, что тег не может начинаться перед, а заканчиваться внутри цикла). Блоку дается имя. Например:

{% block content %}
 тело блока
{% endblock %}

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

Пример наследования шаблонов

 

 Например, структура сайта такова : 

  • шапка (логотип, заголовок страницы, меню);
  • тело страницы;
  • и "подвал" с информацией о правах распространения.

Вот как это выглядит:


 

{% block head %}

{% block title %}{% endblock %}

{% block menu %}{% endblock %}

{% endblock %}

{% block page %}

{% block content %}

{% endblock %}

{% endblock %}

{% block footer %}

{% block copyright %}

{% endblock %}

{% endblock %}

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

 А делать, чтоб добавить правую колонку для вывода списка тегов и последних статей. Возможно мы захотим добавить правую колонку к каким-нибудь другим страницам сайта. Чтобы избежать копирования "двухколоночности", вынесем ее в отдельный шаблон,
переопределив тело страницы у базового.

{% extend "base.htm" %}

{% block page %}

 {% block content %}

 {% endblock %}

 {% block sidebar %}

 {% endblock %}

{% endblock %}


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



{% extend "base_2col.htm" %}

{% block title %}

 Блог

{% endblock %}

{% block sidebar %}

 {% block tags %}

 {% endblock %}

 {% block recent %}

 {% endblock %}

{% endblock %} 

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



{% extend "blog/base.htm" %}

{% block content %}

 {% for article in article_list %}

  «a href="{% url article_view article.id %}"»

  {{ article.title }}

  «/a»

 {% endfor %}

{% endblock %}

Статья:



{% extend "blog/base.htm" %}

{% block title %}

 {{ article.title }} - {{ block.super }}

{% endblock %}

{% block content %}

 {{ article.text }}

{% endblock %}
 

Список статей, у которых есть определенный тег:


{% extend "blog/index.htm" %}


{% block title %}

 {{ tag.title }} - {{ block.super }}

{% endblock %}

{% block content %}

 {{ tag.title }}

 {{ tag.text }}

 {{ block.super }}

{% endblock %} 

В данном случае, мы воспользовались еще одной хитростью. Ведь этот список ничем не отличается от простого списка статей - он просто отфильтрован по дополнительным параметрам. Поэтому мы унаследовали его от списка статей и при перекрытии тела использовали тег {{ block.super }} - вывести все содержимое родительского блока.
Как видно, каждый шаблон очень конкретен и отвечает только за свою функциональность. Ему нет необходимости знать о всей странице в целом.

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

источник: http://www.rusdoc.ru/articles/shablony_django_nasledovanie/16674/

Комментарии