Структура любого каталога хранится в xml файле. В качестве примера можно взять файл catalog.xml из демонстрационного сайта. Файл содержит иерархию категорий, элементов и ярлыков (ссылок на элементы). Ярлыки при отрисовке автоматически преобразуются в элементы, поэтому в дальнейшем их можно не учитывать как самостоятельные логические элементы.
Общая структура файла с дизайнами (catalog_design.xml)
<?xml version="1.0" encoding="windows-1251" ?>
<control-document>
<catalogdesign id="main">
<header><![CDATA[Заголовок]]></header>
<delimiter><![CDATA[Разделитель]]></delimiter>
<item>
<level id="1000" number="1">
<usual><![CDATA[Обычная категория уровня 1]]></usual>
<active><![CDATA[Активная категория уровня 1 и вызов отрисовки следующего уровня (если нужно) через $Children$]]></active>
</level>
<level id="1010" number="2">
...
</level>
</item>
<footer><![CDATA[Подвал]]></footer>
<empty><![CDATA[Когда ничего не найдено]]></empty>
</catalogdesign>
</control-document>
Жирным выделены переменные части, определяемые разработчиком. Тэги CDATA могут отсутствовать, но мы рекомендуем ими обрамлять все блоки HTML для сохранения XML валидности файла с дизайнами.
Внимание: Данный макрос использует файл catalog_design.xml так же как и макрос CatalogFullTree, но в нем не может быть секции <entity ...> и нет разделения на category/element внутри <level ...>. По этой причине совместное использование этих макросов на одном проекте невозможно, а при переходе от использования одного макроса к другому или обратно следует помнить о необходимости добавления или удаления данного тэга.
Алгоритм работы макроса
Система считает, что в момент вызова данного макроса пользователь находится на сайте в пределах какого-то каталога товаров, услуг или любой другой иерархической структуры. И c помощью данного макросе требуется отрисовать некоторое дерево, или его часть, чтобы пользователь смог перемещаться по дереву. То есть, реализовать для пользователя навигацию. Визуально это может быть что-то вроде древовидного меню (одно- или несколькоуровневое), "хлебные крошки", просто список подкатегорий в каталоге товаров или детальное описание конкретной категории, внутри которой сейчас находится пользователь. Но не только.
Обычно навигация по каталогам реализуется в HTML ссылками (A HREF=...), которые должны содержать ключи с предопределенными названиями: sid и iid.
Модель каталога в "Twilight CMS" подразумевает, что пользователь на сайте может находиться либо в категории (папке) и видеть список доступных подкатегорий и элементов (товаров) внутри данной категории, либо на странице с детальным описанием элемента (товара).
В первом случае, в URL обычно передается только параметр sid, в котором должен содержаться идентификатор текущей категории, внутри которой пользователь находится. Параметр может быть пустым или вообще не задан, тогда макрос будет вычислять текущее положение в каталоге по другим признакам.
Во втором случае, в URL обычно задается и sid, и iid. В iid должен быть указан идентификатор конкретного узла (товара), информацию о котором нужно отрисовать на текущей странице. Параметр sid может отсутствовать, тогда система попытается автоматически определить в какой категории находится пользователь (в какой категории находится товар, который пользователь сейчас просматривает, если точнее). Но, поскольку один и тот же товар может быть привязан сразу к нескольким категориям, в неоднозначных ситуациях будет использоваться первое найденное в XML структуре значение. Поэтому, если на странице необходимо отрисовать описание товара и навигацию из какой-то конкретной точки дерева каталога, необходимо в URL на страницу передавать оба ключа: и sid, и iid.
Таким образом, если в файле дизайна мы хотим сделать ссылку на какую-то категорию каталога, то мы должны написать что-то вроде <A HREF="/catalog/?sid=...">...</A>, а если на страницу с товаром - <A HREF="/catalog/?sid=...&iid=...">...</A> или <A HREF="/catalog/?iid=...">...</A>. Вместо /catalog нужно, естественно, указывать alias страницы, которая отрисовывает каталог и содержит макросы отрисовки каталога и навигации по нему.
Ключи sid и iid автоматически получаются из URL макросами CatalogTree, CatalogFullTree и CatalogList, а также другими макросами и механизмами для работы с каталогами. И переименованы быть не могут. Значения данных ключей могут быть заменены на ЧПУ точно также, как и для элементов справочника. Для чего необходимо добавить соответствующее поле в дескриптор сущности в entities.xml.
При отрисовке макроса CatalogTree система проходит последовательно все категории из выбранного каталога, начиная от текущей категории в каталоге.
Текущая категория определяется следующим образом:
- если в URL не передан ключ iid, то есть явно не задан идентификатор просматриваемого пользователем узла дерева в каталоге (например, товара), то:
- если явно задана какая-то папка через ключ categoryid, то считается, что пользователь находится внутри неё,
- иначе, если в URL задан ключ sid, он используется как идентификатор папки, внутри которой сейчас находится пользователь,
- иначе, используется значение из ключа catalogid и считается, что пользователь находится в корневой папке указанного каталога.
- иначе, если iid задан, считается, что пользователь на странице с товаром, и текущая папка берется как родительская папка указанного товара. При этом, все остальные значения (ключ categoryid, sid) игнорируются.
Для каждого пункта каталога из файла с дизайнами производится выбор секции catalogdesign с указанным в ключе design идентификатором. Далее, из секции <item> выделяется секция <level> с number равным уровню элемента в иерархии каталога. Корневой элемент имеет уровень 1, его подкатегории 2, элементы в них 3 и так далее.
Функционирование механизма определения уровня элементов полностью аналогично механизму определения уровня пункта в меню (см. макрос $Menu[]$), поэтому тут можно использовать переменную current (текущий уровень) и простейшие арифметические действия, а также интервалы. Таким образом, допустима конструкция <level number="1..current+2">, которая говорит что данная секция дизайна будет применена для всех категорий и элементов в каталоге, лежащих на уровне от 1 до "текущий уровень + 2". Под текущим уровнем понимается тот уровень, на котором сейчас находится пользователь в каталоге. Если он просматривает категорию третьего уровня, то current=3.
Все секции level в пределах файла catalog_design.xml должны иметь свои уникальные идентификаторы, которые могут быть произвольными строками в пределах допустимых значений для атрибутов тэгов в языке XML. Рекомендуется для простоты использовать символы A-Z, 0-9, "-" и "_", например <level id="uroven_2" number="2">
Внутри выбранной секции используется секция <active>, если категория находятся в ветке, в которой находится сейчас пользователь на сайте, или <usual> для всех остальных случаев. Это нужно для подсветки текущего пути при отрисовке навигации. Если активные пункты и неактивные отличаться по дизайну не должны, то значения этих секций должны быть одинаковы.
Папки, которые помечены в админзоне как неопубликованные в структуре не учитываются.
Если итоговый дизайн для текущего блока оказывается пустым, то на страницу будет выведена секция <empty>.
Вывод атрибутов
Каждый элемент дерева для отрисовки на сайте необходимо использовать в XML файле с дизайном. Каждый товар или папка, описанные некоторой сущностью в entities.xml, имеют набор полей (атрибутов). Каждое поле для текущего (при последовательном переборе во время отрисовки) элемента дерева может быть выведено в нужном месте дизайна через подстановку $Attribute:атрибут$.
В файле catalog_design.xml можно использовать несколько служебных атрибутов, которые не находятся в таблицах с данными, а добавляются Cистемой "на лету".
Перечень дополнительных атрибутов в каталогах