Вывод древовидного рубрикатора каталогов для отрисовки навигационных элементов типа древовидного рубрикатора или "хлебных крошек". В отличие от CatalogList позволяет отрисовывать не только папки, но и элементы каталога.
* более подробно о том, как устроены каталоги в целом написано в статье о макроподстановке CatalogList, здесь описывается лишь часть. касающаяся структуры.
Структура любого каталога хранится в xml файле. В качестве примера можно взять файл catalog.xml из набора demoshop.zip (скачивается из закрытой зоны). Файл содержит иерархию категорий, элементов и ярлыков (ссылок на элементы). Ярлыки при отрисовке автоматически преобразуются в элементы, поэтому в дальнейшем их можно не учитывать как самостоятельные логические элементы.
Общая структура файла с дизайнами (catalog_design.xml)
<?xml version="1.0" encoding="windows-1251" ?>
<control-document>
<entity id="*">
<catalogdesign id="main">
<header><![CDATA[Заголовок]]></header>
<delimiter><![CDATA[Разделитель]]></delimiter>
<item>
<level id="1000" number="1">
<category>
<usual><![CDATA[Обычная категория уровня 1]]></usual>
<active><![CDATA[Активная категория уровня 1 и вызов отрисовки следующего уровня (если нужно) через $Children$]]></active>
</category>
<element>
<usual><![CDATA[Обычный элемент уровня 1]]></usual>
<active><![CDATA[Активный элемент уровня 1]]></active>
</element>
</level>
<level id="1010" number="2">
...
</level>
</item>
<footer><![CDATA[Подвал]]></footer>
<empty><![CDATA[Когда элементов не найдено]]></empty>
</catalogdesign>
</entity>
</control-document>
Жирным выделены переменные части, определяемые разработчиком. Тэги CDATA могут отсутствовать, но мы рекомендуем ими обрамлять все блоки HTML для сохранения XML валидности файла с дизайнами.
Элемент <entity ...> позволяет сделать несколько дизайнов с одинаковым идентификатором для элементов разного типа. Таким образом, возможна отрисовка одним макросом CatalogFullTree сразу всех типов товаров с разными наборами полей. В атрибуте id можно через запятую указывать несколько разных идентификаторов, для которых будет действовать все что находится внутри. Также, можно подставить символ "*", который будет означать "использовать дизайны внутри для всех entity". В принципе, если на проекте всего одна entity, или дизайны для вывода различных entity не отличаются, то секцию <entity ...> можно опустить, что будет эквивалентно указанию id="*".
Обратите внимание, что возможность указывать разные дизайны для разных entity есть только у этого макроса, а у макроса CatalogTree её нет. Соответственно, если в файле catalog_design.xml есть тэг <entity ...>, то данный файл работать под CatalogTree уже не будет.
Алгоритм работы макроса
При отрисовке навигации с помощью данного макроса система проходит последовательно все категории и элементы из выбранного каталога. Для каждого пункта каталога из файла с дизайнами производится выбор секции 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">
Выбрав нужную секцию <level>, система определяет что в данный момент она обрабатывает - категорию или элемент - и выбирает внутри <level> соответствующую секцию <category> или <element>.
Внутри выбранной секции используется секция <active>, если категория или элемент находятся в ветке, в которой находится сейчас пользователь на сайте, или <usual> для всех остальных случаев. Это нужно для подсветки текущего пути при отрисовке навигации. Если активные пункты и неактивные отличаться по дизайну не должны, то значения этих секций должны быть одинаковы.
Папки и элементы каталога, которые помечены в админзоне как неопубликованные не учитываются при отрисовке.
Если итоговый дизайн для текущего блока оказывается пустым, то на страницу будет выведена секция <empty>.
Пример использования данного макроса для вывода развернутого дерева сайтов, сделанных компанией "Страта Технологии" за 2004-2006 годы, можно скачать здесь. Прочитайте readme.txt внутри архива, чтобы узнать как пользоваться примером.
Вывод атрибутов
Каждый элемент дерева для отрисовки на сайте необходимо использовать в XML файле с дизайном. Каждый товар или папка, описанные некоторой сущностью в entities.xml, имеют набор полей (атрибутов). Каждое поле для текущего (при последовательном переборе во время отрисовки) элемента дерева может быть выведено в нужном месте дизайна через подстановку $PointProperty[атрибут]$.
Начиная с версии 4.37 $Attribute:атрибут$ в файле с дизайном может свободно применяться наравне с конструкцией $PointProperty[атрибут]$. В более ранних версиях $Attribute:атрибут$ не применялся или работал неправильно.
В файле catalog_design.xml можно использовать несколько служебных атрибутов, которые не находятся в таблицах с данными, а добавляются Cистемой "на лету".
- childcount - содержит количество элементов в текущей категории (только для категорий);
- folderchildcount - содержит количество папок в текущей категории (только для категорий);
- level - содержит номер уровня вложенности элемента в дереве;
- drillnumber - содержит сквозной номер (от 1 до N) папки или элемента в дереве;
- index - содержит порядковый номер папки или элемента на текущем уровне вложенности;
- pid - содержит идентификатор родительского элемента;
- table и entity содержат имя таблицы и идентификатор сущности для текущего элемента соответственно;
- soul - для элемента, представленного в каталоге "ярлыком" (ссылкой на элемент), будет содержать идентификатор исходного элемента. Для остальных элементов и папок - пустой.
Внимание: при отрисовке навигации по древовидной иерархии большого объема (300+ категорий и несколько тысяч товаров) на одной странице макрос будет значительно замедлять работу сервера. Для чисто навигационных целей в таких случаях предлагается использовать макрос CatalogTree.
Комментарий: до версии 5.13 атрибут index работал как drillnumber, но это вызывало затруднения разработчиков. Поэтому было принято решение унифицировать названия и теперь в рамках всей системы drillnumber обозначает сквозной номер в рамках всей выборки (в данном контексте - всего дерева), а index - просто порядковый номер, в данном контексте - на текущем уровне.