« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
    Популярное
Объявление записи

Изменение должностных окладов

WinAPI. Функции работы с файлами. Часть 3

Описание функций C (Си) / C++ - rename

Функция GetGValue

Инструкции выбора

Пять заблуждений связанных с .NET

Файловые операции с использованием стандартного диалога с анимацией Копирование Файлов

Часть VIII. Интерфейс

С++ Builder: как ускорить компиляцию (часть 2)




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 116
Пользователей: 0

Статьи:: Интернет технологии :: Вебмастеру :: Шаблоны Django. Наследование.



отправить ссылку другу версия для печати  Обсудить на форуме

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

Прочитал статью «Фрагментарное кэширование в MVC веб-фреймворках». Статья описывает проблему кеширования фрагмета отображения, а именно проблему полного разделения контроллера и отображения - контроллер отрабатывает полностью до вызова отображения. Если в отображении мы кешируем фрагмент, это ничего не меняет - контроллер-то уже отработал! В статье описан способ этого избежать: сделать запрос данных "ленивым".



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

Как это сделано в Django?

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

Управляющими элементами шаблонов Django являются переменные, фильтры и теги.

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

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

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

Программист может написать свои фильтры и теги, но об этом позже.

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

Все выше перечисленное тривиально и в той или иной форме есть в любом движке шаблонов. Теперь перейдем к особенностям Django: на тегах block и extend строится наследование шаблонов. Остановимся на них подробнее.

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

Основная фишка шаблонов 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 - пользовательские теги.

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

В нашем примере на странице статьи блога есть 7 блоков. Два из них - логотип и copyright - не нуждаются в данных. Для остальных пяти контроллеру необходимо предоставить шаблону данные. А именно:

  • заголовок статьи;
  • меню;
  • тело статьи;
  • список тегов;
  • последние статьи.

Блоков могло быть намного больше, но непосредственное отношение к статье имеют только заголовок и тело статьи. Зачем статье знать, какие данные нужны этим блокам, откуда и как их получить? Абсолютно незачем - это не ее задача. Django предлагает нам следующее решение этой проблемы.

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

Вот пример тега для вывода списка последних статей в блоге:

# тег
@register.inclusion_tag('blog/article_recent_list.htm')
def blog_recent_articles_list():
	return {
		'article_list': Article.objects.filter(public=True)[:10],
	}

# шаблон
«h4»Последние статьи«/h4»
«ul class="links"»
	{% for article in article_list %}
	«li»«a href="{% url article %}"»{{ article.title}}«/a»«/li»
	{% endfor %}
«/ul»

Еще одним приемуществом такого подхода является то, что данные запрашиваются непосредственно при вставке тега. Если кэшировать несколько тегов, то будут кэшированы результаты их работы - повторно данные запрашиваться не будут! И не надо изобретать велосипеды, как тут ;)

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

Ссылки на официальную документацию:

PS: Это перепечатка с моего блога http://dpp.su/. Кстати, там есть еще несколько менее интересных статей про Django.




Рубрика: Вебмастеру




Вышел MySQL 5.1.30, первый стабильный рели....

MySQL

После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:


Подробнее... | Рубрика: MySQL | Добавлено: 28.11.2008

Тестирование параллельных программ.

Тестирование

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


Подробнее... | Рубрика: Тестирование | Добавлено: 28.11.2008

Архитектура AMD64 (EM64T).

Архитектура AMD

Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.


Подробнее... | Рубрика: Архитектура AMD | Добавлено: 27.11.2008

Остальные статьи:

Платформа 2009. Определяя будущее
Windows Vista Bridge Sample Library - упра...
Оптимизация 64-битных программ
Подгрузка через AJAX HTML-кода, содержащег...
Обзор нового релиза самой мощной Ajax библ...
Firebug 1.3 и 1.4 alpha — что нового и инт...
Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия