Использование принципов вложенности в компонентах NetCat
Концепция осмысленного использования шаблонов компонентов в NetCat, созданная чтобы:
- избежать дублирования кода и упростить поддержку и развитие проекта в условиях его непредсказуемости;
- сформировать логику в голове программиста - отделить общее от частного.
Отсюда идея:
Писать код компонента таким образом, чтобы основная логика была в компоненте и наследовалась в шаблонах. Шаблоны компонента должны по возможности служить модификаторами, надстройками над основным компонентом.
Это должно привести к тому, что:
- для добавления нового поля в компонент, достаточно прописать его вывод только в корневом шаблоне
- для изменений верстки или внешнего вида листинга объектов в некоем частном случае, изменения должны вноситься только в соответствующий ему шаблон компонента
Что это значит?
Это значит, что шаблоны компонента должны дополнять корневой компонент, а не перезаписывать его. В самом компоненте всегда должно храниться "ядро" логики и верстки, а шаблонах - его модификаторы, могущие работать как через php, так и через CSS, путем "обвязки" базовой верстки новым слоем.
Как наследовать?
В Netcat 4.x можно использовать переменные %Suffix%, %Record%, %Prefix%, %Settings%, %Full%
и т.д. - в них содержится код из соответствующих полей корневого компонента.
В Netcat 5.x - то же самое, что и в Netcat 4.x, плюс можно применять конструкцию <? require_once $nc_parent_field_path; ?>
- она используется для наследования любого поля, в том числе действий после добавления/изменения и т.п.
Что значит дополнять корневой компонент, я не понимаю?
Значит, написать, например, в префиксе шаблона - %Prefix%
и затем вставить свой архиполезный код, не дублирующий тот, который уже есть в %Prefix%
.
Пример из жизни
Задача: выводить на сайте свежие акции (о скидках, распродажах и т.д.) по критерию: отображаются только те акции, у которых дата окончания в будущем относительно сегодняшнего дня (finishDate >= CURDATE()
). При этом:
- акции связаны с компаниями, которые их предлагают;
- и с товарами, на которые эти акции применяются. Соответственно, акции должны дополнительно выводиться на страницах компаний и на страницах товаров.
- а еще хочется этими акциями управлять, включать-выключать и видеть завершенные.
- а на странице товара акции должны подсвечиваться при наведении.
Что делать? Сначала подумать.
Выборка объектов. По итогам дум получаем такую картину:
- основной компонент должен выводить листинг акций по указанному критерию:
finishDate >= CURDATE()
(это попадает в системные настройки компонента); - в шаблоне "На страницу компании" наследуется этот критерий плюс добавляется критерий, указывающий на принадлежность акции компании:
Message_ID IN (список ID акций)
; - в шаблоне "На страницу товара" наследуется этот критерий плюс добавляется критерий, указывающий на принадлежность акции товару:
Message_ID IN (список ID акций)
Видим, что в системных настройках двух шаблонов мы совершаем одинаковые выборки. Значит, этот одинаковый код надо вынести в основной компонент, а в системных настройках шаблонов наследовать его через %Settings%
- нужен шаблон вывода всех акций для администратора с возможностью посмотреть завершенные и выключенные акции.
Значит, в его системных настройках должно быть примерно следующее:
%Settings% if ($actions) { //GET-параметр, в зависимости от которого формируется выборка switch ($actions) { case "showAll": //показать все $ignore_check = 1; break; case "showFinished": //показать завершенные $ignore_check = 1; $query_where = "a.finishDate < CURDATE()"; break; case "showOff": $ignore_check = 1; $query_where = "a.Checked = 0 OR a.finishDate = 0 OR a.finishDate IS NULL"; break; } }
С логикой вывода объектов и ее наследованием разобрались. Теперь надо сделать верстку.
Верстка
Базовую верстку делаем в корневом компоненте, оборачивая листинг объектов классом actions. Используя css-компилятор LESS? внутри этого класса пишем нужные стили, соответственно, любой вложенный в actions класс не влияет ни на что другое, кроме акций.
Итак, в корневом компоненте это выглядит так:
- Префикс:
<div class='actions'>
- Объект в списке:
<div class='object'> ... вывод полей объекта ... </div>
- Суффикс:
</div>
В LESS пишем:
.actions { margin: 10px 0; .object { color: #000; } }
Для страницы компании нет никаких дополнительных требований к внешнему виду, значит, просто наследуем родителя:
- Префикс:
%Prefix%
- Объект в списке:
%Record%
- Суффикс:
%Suffix%
А для страницы товара мы хотели подсветить акцию при наведении мыши:
- Префикс:
<div class='actions actions-for-goods'>
- Объект в списке:
%Record%
(наследуем) - Суффикс:
%Suffix%
(наследуем)
Далее идем и в LESS и дополняем его такими строками:
.actions-for-goods { .object { // реакция на наведение мыши &:hover { background: #f2fbfe; cursor: pointer; } } }
Все, требуемый результат получен. Ничего нигде не пересеклось и не наложилось друг на друга. Мы просто в шаблоне для страницы товара дописали дополнительный "обвязывающий" класс actions-for-goods, внутри которого находятся нужные стили и который применен и работает только на странице товара.
Описанный выше прием доказал на практике свою "профпригодность" и, очевидно, должен использоваться при разработке и поддержке любого более-менее сложного проекта на NetCat.