====== Композиция шаблонов: включение(include), обворачивание(wrap) и переиспользование(reuse) шаблонов ====== ===== Компиляция MACRO шаблонов ===== MACRO содержит различные средства, которые позволяют собирать конечные шаблоны из набора других шаблонов: * **Включение (include)** - включение одного шаблона в другой. * **Обворачивание (wrap)** - обворачивание одного шаблона другим. * **Переиспользование (reuse)** - использование части текущего шаблона несколько раз в различных местах. **MACRO компилирует шаблоны только целиком!** То есть сначала обрабатываются все теги, такие как [[limb3:ru:packages:macro:tags:core_tags:include_tag| {{include}}]], [[limb3:ru:packages:macro:tags:core_tags:wrap_tag| {{wrap}}]], [[limb3:ru:packages:macro:tags:core_tags:into_tag| {{into}}]], [[limb3:ru:packages:macro:tags:core_tags:apply_tag| {{apply}}]] , и только затем окончательно создается откомпилированный шаблон. Именно поэтому разбиение шаблона на составляющие в MACRO с точки зрения выполнения конечного шаблона ничего не стоит (лишь увеличивается время компиляции). Это дает нам возможность выносить в отдельные шаблоны все, что повторяется в нескольких файлах. Цель данной страницы - показать способы "снижения дублирования" в MACRO-шаблонах, то есть как максимально эффективно использовать все возможности MACRO по композиции шаблонов. ===== Включение (include). Использование тега {{include}} ===== Включение (include) одного шаблона в другой. Include в MACRO осуществляется посредством [[limb3:ru:packages:macro:tags:core_tags:include_tag|тега {{include}}]]. По-умолчанию, включаемый файл компилируется как обычный шаблон. {{include file='header.phtml'}} [...content...] {{include file='footer.phtml'}} Если вы используете MACRO совместно с пакетом VIEW, и в атрибуте file используется абсолютное значение (начинается с **/** или с **c:/**), тогда MACRO подключает шаблон по абсолютному пути. В противном случае - пытается найти шаблон через механизм подключения шаблонов. Стоит также обратить внимание, что при включении шаблона включаемый шаблон должен быть сбалансированным с точки зрения MACRO-тегов. То есть если тег предусматривает закрывающий тег, например, тег [[limb3:ru:packages:macro:tags:list_tags:list_tag| {{list}}]] или [[limb3:ru:packages:macro:tags:pager_tags:pager_tag| {{pager}}]], значит и закрываться он должен в том же файле. ===== Обворачивание (wrap) ===== ==== Введение в обворачивание шаблонов ==== Обворачивание (wrap) -- это вставка текущего шаблона в определенное место другого шаблона. С обворачиванием шаблонов связаны следующие термины: * Текущий шаблон -- который содержит команды по обворачиванию (в нем содержатся теги [[limb3:ru:packages:macro:tags:core_tags:wrap_tag| {{wrap}}]]) * Базовый шаблон -- в который осуществляется вставка текущего шаблона. * Контейнер вставки или слот (slot/placeholder) -- находится в базовом шаблоне и помечает места вставки. Обворачивание производится при помощи [[limb3:ru:packages:macro:tags:core_tags:wrap_tag|тега {{wrap}}]]. Слот для вставки помечается в базовом шаблоне [[limb3:ru:packages:macro:tags:core_tags:slot_tag|тегом {{slot}}]]. Рассмотрим небольшой пример: **page.html** -- базовый шаблон [...meta...] {{slot id='content'/}} **my_page.html** -- текущий шаблон {{wrap with='page.html' into='content'}} [...content...] {{/wrap}} В результате получим нечто: [...meta...] [...content...] ==== Использование тега {{wrap}}. Множественное обворачивание. Тег {{into}} ==== Разберем подробнее, как работает [[limb3:ru:packages:macro:tags:core_tags:wrap_tag|тег {{wrap}}]]. %%{{wrap}}%% требует закрывающего тега. Обворачиваемой считается та часть текущего шаблона, что обрамлена в рамки тега %%{{wrap}}%%. По-умолчанию %%{{wrap}}%% вставляет все свое содержимое в слот, указаный при помощи атрибута **into**. Однако можно различные части текущего шаблона отправить в различные слоты базового шаблона. Для этого используется [[limb3:ru:packages:macro:tags:core_tags:into_tag|тег {{into}}]]. Поясним это все на примере: Допустим есть базовый шаблон страницы page.html: {{slot id='content'/}} Также шаблон дополнительного дизайна layout.html с двумя местами для вставки (как бы второй базовый шаблон):
{{slot id='main'/}}
И теперь текущий шаблон display.html: {{wrap with='page.html' into='content'}} {{wrap file='layout.html'}} {{into slot='header'}}My Header{{/into}} {{into slot='main'}}My Complex content{{/into}} {{/wrap}} {{/wrap}} На выходе получим:
My Complex content
Необходимо пояснить, как именно компилируется шаблон в данном случае. Сначала обрабатывается первый %%{{wrap}}%% и мы получаем на 1-м шаге компиляции следующий шаблон: {{wrap with='layout.html'}} {{into slot='header'}}My Header{{/into}} {{into slot='main'}}My Complex content{{/into}} {{/wrap}} Затем обрабатывается второй %%{{wrap}}%% и условно получается:
{{slot id='main'/}}
{{into slot='header'}}My Header{{/into}} {{into slot='main'}}My Complex content{{/into}}
В результате работы тегов %%{{into}}%% получается конечный результат. Если %%{{into}}%% тег находит вне %%{{wrap}}%% тега, тогда он пытается найти соответстувующий тег %%{{slot}}%% начиная с корня дерева компилируемого шаблона. ===== Повторное использование части текущего шаблона ===== Представим, что вам необходимо вывести 2 списка элементов одинакомым образом, однако имеющим различные источники данных. Например, на первой странице раздела нам нужно вывести лучшие товары и остальные товары раздела. Первое решение - это вынести повторяющуюся часть шаблона в отдельный файл и подключать его 2 раза при помощи тега %%{{include}}%%. Это хороший вариант, если вы собираетесь использовать этот выделенный шаблон несколько раз еще в других шаблонах. Если же общая часть используется только в рамках одного шаблона, то этих целей целесообразно использовать комбинацию [[limb3:ru:packages:macro:tags:core_tags:template_tag|тега {{template}}]] и нескольких [[limb3:ru:packages:macro:tags:core_tags:apply_tag|тегов {{apply}}]]. Например: {{template name="photo_tpl"}} {$item.ctime|date:"d.m.Y"} {$item.title} {$item.title} {$item.member.nick} предварительный просмотр {{/template}}

Лучшие фото рубрики {$#category.title}

{{list using="$#best_photos" as="$photo"}} {{/list}}

Все фото рубрики {$#category.title}

{{list using="$#photos" as="$photo"}} {{/list}}
Сам тег %%{{template}}%% ничего не рендерит. Только вызовы %%{{apply}}%% вставляют часть этого кода в нужное место. Обратите внимание, что на уровне откомплированного шаблона %%{{template}}%% создает отдельный метод, а %%{{apply}}%% - это по сути вызов этого метода. Поэтому то, что находится в рамках %%{{template}}%% - это по сути отдельный локальный контекст и локальные переменные в нем будут не видны, и их нужно туда передавать, что и реализовано в приведенном примере.