====== Композиция шаблонов: включение(include) и обворачивание(wrap) шаблонов ====== ===== Компиляция WACT шаблонов ===== WACT содержит различные средства, которые позволяют собирать конечные шаблоны из набора других шаблонов: * **Включение (include)** - включение одного шаблона в другой. * **Обворачивание (wrap)** - обворачивание одного шаблона другим. **Wact компилирует шаблоны только целиком!** То есть сначала обрабатываются все include и wrap теги, и только затем создается откомпилированный шаблон. Именно поэтому разбиение шаблона на составляюще в WACT практически ничего не стоит (лишь увеличивается незначительно время компиляции). Это дает нам возможность выносить в отдельные шаблоны все, что повторяется в нескольких файлах. Цель данной страницы - показать способы "снижения дублирования" в WACT-шаблонах, то есть как максимально эффективно использовать все возможности WACT по композиции шаблонов. ===== Включение (include). Использование тега ===== Включение (include) одного шаблона в другой. Include в WACT осуществляется посредством тега [[limb3:ru:packages:wact:tags:core_tags:core_include_tag|]]. По-умолчанию, включаемый файл компилируется как обычный шаблон. [...content...] Если вы используете WACT совместно с пакетом WEB_APP, и в атрибуте file используется абсолютное значение (начинается с **/** или с **c:/**), тогда WACT подключает шаблон по абсолютному пути. В противном случае - пытается найти шаблон через механизм подключения шаблонов. Компиляцию включаемого шаблона можно отключить, если использовать атрибут literal, например: . ===== Обворачивание (wrap) ===== ==== Введение в обворачивание шаблонов ==== Обворачивание (wrap) - это вставка шаблона в определенное место другого шаблона. С обворачиванием шаблонов связаны следующие термины: * Текущий шаблон - который содержит команды по обворачиванию (в нем содержатся теги ) * Базовый шаблон - в который осуществляется вставка текущего шаблона. * Контейнер вставки (placeholder) - находится в базовом шаблоне и помечает места вставки. Обворачивание производится при помощи тега [[limb3:ru:packages:wact:tags:core_tags:core_wrap_tag|]]. Контейнер обычно помечается тегом [[limb3:ru:packages:wact:tags:core_tags:core_placeholder_tag|]]. Рассмотрим небольшой пример: **page.html** - базовый шаблон [...meta...] **my_page.html** - текущий шаблон [...content...] В результате получим нечто: [...meta...] [...content...] ==== Использование тега . Множественныое обворачивание ==== Разберем подробнее, как работает тег [[limb3:ru:packages:wact:tags:core_tags:core_wrap_tag|]]. требует закрывающего тега. Обворачиваемой считается та часть текущего шаблона, что обрамлена в рамки тега . Если тег не содержит атрибута file, тогда обворачивание производится в шаблон, который был указан родительским тегом . Таким образом мы можем как бы указать сначала целевой файл, а затем только указать какие части и куда обвернуть. Поясним это все на примере: Допустим есть базовый шаблон страницы page.html: Также шаблон дополнительного дизайна layout.html с двумя местами для вставки (как бы второй базовый шаблон):
И теперь текущий шаблон display.html: My Header My Complex content На выходе получим:
My Complex content
Необходимо пояснить, как именно компилируется шаблон в данном случае. Сначала обрабатывается первый и мы получаем на 1-м шаге компиляции следующий шаблон: My Header My Complex content Затем обрабатывается второй и условно получается:
My Header My Complex content
Обратите внимание, что дочерние теги (без атрибута file) могут найти контейнеры вставки только в отмеченной зоне (только внутри шаблона, указанного родительским ). В результате работы дочерних получается конечный результат. ==== Произвольные контейнеры вставки ==== Контейнер вставки не обязательно должен быть реализован при помощи тега [[limb3:ru:packages:wact:tags:core_tags:core_placeholder_tag|]]. Для этих целей можно использовать вообще любой тег, например
. Необходимо будет лишь указать, что этот тег должен обрабатываться как тег с активным компонентом и дать ему идентификатор. Это можно сделать при помощи одного атрибута: **wact:id**, например:
Content will be placed here
можно использовать по-разному: * вставлять контент в конец содержимого контейнера. * заменять весь контент контейнера . Для этого теперь есть 2 атрибута: * **in**, например ... * **as**, например ... В первом случае содержимое между будет вставлено сразу же после содержимого контейнера вставки, во втором - полностью заменит контент внутри контейнера. ==== Контексты и множественное обворачивание ==== Самый сложный момент, который обычно представляет трудность для верстальщиков - это понимание, как будет выглядеть откомпилированный шаблон, а также понимание структуры контейнеров данных, которая будет существовать в шаблоне после компиляции. Разберем небольшой пример (предупреждаем, он может показаться весьма нетривильным для понимания). Путь у нас есть базовый шаблон page.html, в котором есть 2 контейнера вставки:

Предположим, что у нас есть такой текущий шаблон: {$title} {$content} На первый взгляд все нормально, мы должны получить конечный шаблон, где из контейнера данных my_data будут выводиться значения title и content. Однако это вовсе не так!! На самом деле шаблон откомпилируется схематично следующим образом:

{$title}

{$content}
То есть по сути внутри контейнера данных ничего нет! А переменные, которые в исходном шаблоне как бы относились к контексту my_data, на самом деле в откомпилированном шаблоне относятся именно к корневому контейнеру данных. Здесь есть 3 решения: * Вынести наверх, до тега * Создать отдельный шаблон (например, layout.html), который будет содержать разметку, а обворачивание в этот шаблон сделать уже внутри * Брать данные только из корневого контекста Первый вариант будет выглядеть сдедующим образом (изменится только текущий шаблон): {$title} {$content} Самый большой недостаток этого подхода - это то, что теперь весь шаблон заключен в активный компонент тега , то есть мы как бы имеем теперь 2 корневых шаблона. Это может повлять на работу некоторых шаблонов, которые выводили некоторые переменные, считая что текущий контейнер будет глобальным, например, {$meta_keywords} вместо {$#meta_keywords}. Второй способ более правильный, но требует выделения еще одного шаблона. Вот как будут выглядеть все наши шаблоны: Базовый шаблон **page.html** Шаблон **layout.html**

{$title}

{$content}
И наш текущий шаблон: {$title} {$content} Теперь все будет работать как ожидается.