Привелось мне тут на базовом шаблоне интернет-магазина делать меню, состоящее не только из разделов определенного инфоблока, но и из списка инфоблоков.
Иными словами, есть инфоблок «Одежда» со своими плюшками, и он отнесен в отдельную папку на сайте, а в нем есть свои разделы…
И есть раздел «Игрушки», где все также свое.
Но базовый компонент Битрикса menu.section строит структуру разделов только для 1 инфоблока, что мне не удобно.
Как видно, что одежды тут и вовсе нет.
Изменив .left.menu_ext.php в строке
if ($arIBlock = $dbIBlock->GetNext())
заменив IF на While
while ($arIBlock = $dbIBlock->GetNext())
И перенеся array_merge в тело цикла
while ($arIBlock = $dbIBlock->GetNext()) { if(defined("BX_COMP_MANAGED_CACHE")) $GLOBALS["CACHE_MANAGER"]->RegisterTag("iblock_id_".$arIBlock["ID"]); if($arIBlock["ACTIVE"] == "Y") { $aMenuLinksExt = $APPLICATION->IncludeComponent("bitrix:menu.sections", "", array( "IS_SEF" => "Y", "SEF_BASE_URL" => "", "SECTION_PAGE_URL" => $arIBlock['SECTION_PAGE_URL'], "DETAIL_PAGE_URL" => $arIBlock['DETAIL_PAGE_URL'], "IBLOCK_TYPE" => $arIBlock['IBLOCK_TYPE_ID'], "IBLOCK_ID" => $arIBlock['ID'], "DEPTH_LEVEL" => "1", "CACHE_TYPE" => "N", ), false, Array('HIDE_ICONS' => 'Y')); } $aMenuLinks = array_merge($aMenuLinks, $aMenuLinksExt); }
Тогда получаем меню тупо из разделов
Видим, что одежда появилась, но такое меню уже займет половину экрана, а если подключить все, что есть в магазине?!
Сохраняем изменения .left.menu_ext.php и делаем свой компонент menu.sections.
Я его отнес в свое пространство компонентов и чуть модифицировал.
<? if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); /** @var CBitrixComponent $this */ /** @var array $arParams */ /** @var array $arResult */ /** @var string $componentPath */ /** @var string $componentName */ /** @var string $componentTemplate */ /** @global CDatabase $DB */ /** @global CUser $USER */ /** @global CMain $APPLICATION */ if(!isset($arParams["CACHE_TIME"])) $arParams["CACHE_TIME"] = 36000000; $arParams["ID"] = intval($arParams["ID"]); $arParams["IBLOCK_ID"] = intval($arParams["IBLOCK_ID"]); $arParams["DEPTH_LEVEL"] = intval($arParams["DEPTH_LEVEL"]); if($arParams["DEPTH_LEVEL"]<=0) $arParams["DEPTH_LEVEL"]=1; $arResult["SECTIONS"] = array(); $arResult["ELEMENT_LINKS"] = array(); if($this->StartResultCache()) { if(!CModule::IncludeModule("iblock")) { $this->AbortResultCache(); } else { $arFilter = array( IBLOCK_ID"=>$arParams["IBLOCK_ID"], "GLOBAL_ACTIVE"=>"Y", "IBLOCK_ACTIVE"=>"Y", "<="."DEPTH_LEVEL" => $arParams["DEPTH_LEVEL"], ); $arOrder = array( "left_margin"=>"asc", ); $rsSections = CIBlockSection::GetList($arOrder, $arFilter, false, array( "ID", "DEPTH_LEVEL", "NAME", "SECTION_PAGE_URL", "IBLOCK_ID", )); if($arParams["IS_SEF"] !== "Y") $rsSections->SetUrlTemplates("", $arParams["SECTION_URL"]); else $rsSections->SetUrlTemplates("", $arParams["SEF_BASE_URL"].$arParams["SECTION_PAGE_URL"]); while($arSection = $rsSections->GetNext()) { //******* САМОЕ ИНТЕРЕСНОЕ $IBLOCK=GetIBlock($arSection["IBLOCK_ID"]); if ($prevIBLID!==$IBLOCK["ID"]){ $arResult["SECTIONS"][] = array( "ID" => $IBLOCK["ID"], "DEPTH_LEVEL" => 0, "~NAME" => $IBLOCK["NAME"], "~SECTION_PAGE_URL" => $IBLOCK["LIST_PAGE_URL"], ); $arResult["ELEMENT_LINKS"][0] = array($IBLOCK["LIST_PAGE_URL"]); $prevIBLID=$IBLOCK["ID"]; } //******* САМОЕ ИНТЕРЕСНОЕ ЗАКОНЧИЛОСЬ, но ниже есть плюшки $arResult["SECTIONS"][] = array( "ID" => $arSection["ID"], "DEPTH_LEVEL" => $arSection["DEPTH_LEVEL"], "~NAME" => $arSection["~NAME"], "~SECTION_PAGE_URL" => $arSection["~SECTION_PAGE_URL"], ); $arResult["ELEMENT_LINKS"][$arSection["ID"]] = array(); } $this->EndResultCache(); } } //In "SEF" mode we'll try to parse URL and get ELEMENT_ID from it if($arParams["IS_SEF"] === "Y") { $engine = new CComponentEngine($this); if (CModule::IncludeModule('iblock')) { $engine->addGreedyPart("#SECTION_CODE_PATH#"); $engine->setResolveCallback(array("CIBlockFindTools", "resolveComponentEngine")); } $componentPage = $engine->guessComponentPath( $arParams["SEF_BASE_URL"], array( "section" => $arParams["SECTION_PAGE_URL"], "detail" => $arParams["DETAIL_PAGE_URL"], ), $arVariables ); if($componentPage === "detail") { CComponentEngine::InitComponentVariables( $componentPage, array("SECTION_ID", "ELEMENT_ID"), array( "section" => array("SECTION_ID" => "SECTION_ID"), "detail" => array("SECTION_ID" => "SECTION_ID", "ELEMENT_ID" => "ELEMENT_ID"), ), $arVariables ); $arParams["ID"] = intval($arVariables["ELEMENT_ID"]); } } if(($arParams["ID"] > 0) && (intval($arVariables["SECTION_ID"]) <= 0) && CModule::IncludeModule("iblock")) { $arSelect = array("ID", "IBLOCK_ID", "DETAIL_PAGE_URL", "IBLOCK_SECTION_ID"); $arFilter = array( "ID" => $arParams["ID"], "ACTIVE" => "Y", "IBLOCK_ID" => $arParams["IBLOCK_ID"], ); $rsElements = CIBlockElement::GetList(array(), $arFilter, false, false, $arSelect); if(($arParams["IS_SEF"] === "Y") && (strlen($arParams["DETAIL_PAGE_URL"]) > 0)) $rsElements->SetUrlTemplates($arParams["SEF_BASE_URL"].$arParams["DETAIL_PAGE_URL"]); while($arElement = $rsElements->GetNext()) { $arResult["ELEMENT_LINKS"][$arElement["IBLOCK_SECTION_ID"]][] = $arElement["~DETAIL_PAGE_URL"]; } } $aMenuLinksNew = array(); $menuIndex = 0; $previousDepthLevel = 1; // далее везде $arSection["DEPTH_LEVEL"]+1, чтобы компенсировать нулевой уровень foreach($arResult["SECTIONS"] as $arSection) { if ($menuIndex > 0) $aMenuLinksNew[$menuIndex - 1][3]["IS_PARENT"] = $arSection["DEPTH_LEVEL"]+1 > $previousDepthLevel; $previousDepthLevel = $arSection["DEPTH_LEVEL"]+1; $arResult["ELEMENT_LINKS"][$arSection["ID"]][] = urldecode($arSection["~SECTION_PAGE_URL"]); $aMenuLinksNew[$menuIndex++] = array( htmlspecialcharsbx($arSection["~NAME"]), $arSection["~SECTION_PAGE_URL"], $arResult["ELEMENT_LINKS"][$arSection["ID"]], array( "FROM_IBLOCK" => true, "IS_PARENT" => false, "DEPTH_LEVEL" => $arSection["DEPTH_LEVEL"]+1, ), ); } return $aMenuLinksNew; ?>
Красным выделено то, что изменилось. И, конечно, в .left.menu_ext.php меняем вызов компонента в строке
$aMenuLinksExt = $APPLICATION->IncludeComponent("bitrix:menu.sections", "", array(
на
$aMenuLinksExt = $APPLICATION->IncludeComponent("spl:menu.sections", "", array(
Где «spl» — это мое пространство имен.
Тогда получаем такое
Живой просмотр на сайте http://чегохотят.дети/