Мне никогда не нравилось использовать в качестве меню стандартный компонент bitrix:catalog.section.list
, который «Структура разделов», хотя при разработке любого каталога или интернет-магазина, он просто незаменим. А когда дело доходит до многоуровневых каталогов, мозг потихоньку начинает взрываться от отсутствия древовидного массива.
Дано:
- Битрикс с каталогом и неограниченной вложенностью разделов;
- Необходимость организовать настоящую навигацию по каталогу с автогенерацией и активным пунктом;
- Желание получить удобный шаблон меню.
Решение.
Итак, в первую очередь — создание типа меню для разделов каталога, для этого переходим в раздел Настройки > Настройки продукта > Настройки модулей > Управление структурой административной части сайта и создаем новый тип меню. Для примера: тип — catalog, название — «Меню каталога»
Следующим шагом встроим в шаблон сайта в нужном месте bitrix:menu
. Далее в режиме правки выбираем «копировать шаблон компонента», называем новый шаблон «sections», ставим нужный уровень вложенности меню.
Должно получиться что-то типа того:
<? $APPLICATION->IncludeComponent( "bitrix:menu", "sections", array( "ALLOW_MULTI_SELECT" => "Y", "CHILD_MENU_TYPE" => "left", "COMPONENT_TEMPLATE" => "tree", "DELAY" => "N", "MAX_LEVEL" => "4", "MENU_CACHE_GET_VARS" => array( ), "MENU_CACHE_TIME" => "3600", "MENU_CACHE_TYPE" => "N", "MENU_CACHE_USE_GROUPS" => "Y", "ROOT_MENU_TYPE" => "catalog", "USE_EXT" => "N" ), false );?>
Затем, в корне сайта или в нужном разделе сайта создаем файл .catalog.menu.php, который будет генерировать наше меню. В него вставляем:
<?php if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); global $APPLICATION; $aMenuLinksExt = $APPLICATION->IncludeComponent( "bitrix:menu.sections", "", array( "IS_SEF" => "Y", "ID" => $_REQUEST["ID"], "IBLOCK_TYPE" => "catalog", "IBLOCK_ID" => 2,//Укажите реальный ID инфоблока каталога "SECTION_URL" => "", "DEPTH_LEVEL" => "4",//Количество уровней меню "CACHE_TYPE" => "Y",//Настройки кеширования "CACHE_TIME" => "3600", //Настройки ЧПУ каталога "SEF_BASE_URL" => "/catalog/", "SECTION_PAGE_URL" => "#SECTION_CODE_PATH#/", "DETAIL_PAGE_URL" => "#SECTION_CODE_PATH#/#ELEMENT_CODE#/" ), false ); $aMenuLinks = array_merge($aMenuLinksExt, $aMenuLinks);
В шаблоне меню, рядом с template.php, создаем файл result_modifier.php и наполняем его:
<?php if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); $menuList = array(); $lev = 0; $lastInd = 0; $parents = array(); foreach ($arResult as $arItem) { $lev = $arItem['DEPTH_LEVEL']; if ($arItem['IS_PARENT']) { $arItem['CHILDREN'] = array(); } if ($lev == 1) { $menuList[] = $arItem; $lastInd = count($menuList)-1; $parents[$lev] = &$menuList[$lastInd]; } else { $parents[$lev-1]['CHILDREN'][] = $arItem; $lastInd = count($parents[$lev-1]['CHILDREN'])-1; $parents[$lev] = &$parents[$lev-1]['CHILDREN'][$lastInd]; } } $arResult = $menuList;
В результате мы получаем красивый древовидный массив и очень простой код шаблона:
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); if (!empty($arResult)):?> <?function getItems($a) { foreach($a as $arItem):?> <li<?=$arItem["SELECTED"]?' class="active"':''/*выделяем активный пункт (текущий раздел)*/?> <a href="<?=$arItem["LINK"]?>"><?=$arItem["TEXT"]?></a> <?if($arItem["IS_PARENT"]):?> <ul> <?getItems($arItem["CHILDREN"])?> </ul> <?endif?> </li> <?endforeach; } getItems($arResult);?> <?endif?>
Здесь вариант для наглядности, однако, с точки зрения Bitrix Framework, правильнее будет вынести саму функцию в файл /bitrix/php_interface/init.php (если его нет, то создайте, если есть, то просто в конце допишите указанный ниже код), а её вызов оставить в шаблоне.
init.php:
function getItems($a) { foreach($a as $arItem):?> <li<?=$arItem["SELECTED"]?' class="active"':''?> <a href="<?=$arItem["LINK"]?>"><?=$arItem["TEXT"]?></a> <?if($arItem["IS_PARENT"]):?> <ul> <?getItems($arItem["CHILDREN"])?> </ul> <?endif?> </li> <?endforeach; }
template.php:
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); getItems($arResult);
Встречал такой интересный вопрос: почему в Битриксе не додумались сделать древовидный массив меню?
Суть вот в чем: во-первых, мы не знаем сколько будет уровней в массиве, поэтому нам пришлось применять рекурсию. Для программиста это легко и просто, но представьте себя на месте верстальщика, который виртуозно расставляет теги, прописывает стили и прошел курс верстки шаблонов под Битрикс. Он не имеет понятия чем отличается цикл от рекурсии, но знает в какой папке должен находиться HTML-код шаблона. Если так и не поняли, то прочтите статью заново и всё станет на свои места 🙂
function getItems($a) {
foreach($a as $arItem):?>
<li ><a href="»>
)