Чтобы создать компонент с древовидным списком разделов и элементами инфоблока для подключения в .left.menu_ext.php, нужно адаптировать компонент для работы в контексте левого меню. Основная задача — вывести разделы и элементы в виде дерева, которое будет интегрировано в левое меню сайта.
1. Структура компонента
Создайте папку для компонента в директории /local/components/
.
Например:
/local/components/custom/section.tree.menu/
Внутри создайте следующие файлы:
.description.php
— описание компонента.class.php
— основной код компонента.
2. Описание компонента (.description.php)
Этот файл описывает параметры компонента.
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
$arComponentDescription = [
'NAME' => 'Древовидное меню разделов с элементами',
'DESCRIPTION' => 'Получает разделы инфоблока в виде пунктов для левого меню',
'PATH' => [
'ID' => 'custom',
'NAME' => 'Кастомные компоненты',
],
];
3. Основной код компонента (class.php)
Этот файл содержит логику компонента.
<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
class SectionTreeMenuComponent extends CBitrixComponent
{
// Подготовка параметров
public function onPrepareComponentParams($arParams)
{
if (!isset($arParams['CACHE_TIME'])) {
$arParams['CACHE_TIME'] = 36000;
}
return $arParams;
}
// Инициализация компонента
public function executeComponent()
{
if ($this->startResultCache()) {
if (CModule::IncludeModule('iblock')) {
$this->arResult = $this->buildMenu($this->getSectionTree());
$this->endResultCache();
} else {
$this->abortResultCache();
}
}
return $this->arResult;
}
// Получение дерева разделов с элементами
protected function getSectionTree()
{
$iblockId = $this->arParams['IBLOCK_ID']; // ID инфоблока
$sections = [];
$elements = [];
// Получаем разделы
$rsSections = CIBlockSection::GetList(
['LEFT_MARGIN' => 'ASC'],
['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'],
false,
['ID', 'NAME', 'DEPTH_LEVEL', 'IBLOCK_SECTION_ID', 'SECTION_PAGE_URL']
);
while ($section = $rsSections->Fetch()) {
$sections[$section['ID']] = $section;
}
// Получаем элементы
$rsElements = CIBlockElement::GetList(
[],
['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'],
false,
false,
['ID', 'NAME', 'IBLOCK_SECTION_ID', 'DETAIL_PAGE_URL']
);
while ($element = $rsElements->Fetch()) {
$elements[$element['IBLOCK_SECTION_ID']][] = $element;
}
// Формируем дерево
$tree = $this->buildTree($sections, $elements);
return $tree;
}
// Построение дерева разделов с элементами
protected function buildTree($sections, $elements)
{
$tree = [];
// Сначала создаём плоский массив с указанием родительских разделов
foreach ($sections as $id => $section) {
$sections[$id]['CHILDREN'] = []; // Инициализируем массив для дочерних разделов
$sections[$id]['ELEMENTS'] = isset($elements[$id]) ? $elements[$id] : []; // Добавляем элементы
}
// Строим дерево
foreach ($sections as $id => $section) {
if ($section['IBLOCK_SECTION_ID']) {
// Если у раздела есть родитель, добавляем его в CHILDREN родителя
$sections[$section['IBLOCK_SECTION_ID']]['CHILDREN'][] = &$sections[$id];
} else {
// Если это корневой раздел, добавляем его в дерево
$tree[] = &$sections[$id];
}
}
return $tree;
}
// Функция построения пунктов меню
protected function buildMenu($menuItems)
{
$aMenuLinks = [];
$this->addMenuItems($aMenuLinks, $menuItems);
return $aMenuLinks;
}
// Функция для рекурсивного добавления пунктов меню
function addMenuItems(&$aMenuLinks, $items, $depthLevel = 1)
{
foreach ($items as $item) {
// Добавляем раздел
$aMenuLinks[] = [
$item['NAME'], // Название раздела
$item['SECTION_PAGE_URL'], // Ссылка на раздел
[],
[
'FROM_IBLOCK' => true,
'IS_PARENT' => false,
'DEPTH_LEVEL' => $depthLevel,
],
];
// Добавляем элементы раздела
if (!empty($item['ELEMENTS'])) {
$aMenuLinks[count($aMenuLinks) - 1][3]['IS_PARENT'] = true;
foreach ($item['ELEMENTS'] as $element) {
$aMenuLinks[] = [
$element['NAME'], // Название элемента
$element['DETAIL_PAGE_URL'], // Ссылка на элемент
[],
[
'FROM_IBLOCK' => true,
'IS_PARENT' => false,
'DEPTH_LEVEL' => $depthLevel + 1,
],
];
}
}
// Рекурсивно добавляем дочерние разделы
if (!empty($item['CHILDREN'])) {
$aMenuLinks[count($aMenuLinks) - 1][3]['IS_PARENT'] = true;
$this->addMenuItems($aMenuLinks, $item['CHILDREN'], $depthLevel + 1);
}
}
}
}
4. Подключение компонента в .left.menu_ext.php
Чтобы подключить компонент в левом меню, откройте файл .left.menu_ext.php и добавьте вызов компонента:
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();
/** @global CMain $APLICATION */
/** @var array $aMenuLinks */
global $APPLICATION;
$aMenuLinksExt = $APPLICATION->IncludeComponent(
'custom:section.tree.menu',
'',
[
'IBLOCK_ID' => 5, // ID инфоблока
]
);
$aMenuLinks = array_merge($aMenuLinks, $aMenuLinksExt);
Итог
Теперь у вас есть компонент, который выводит древовидное меню разделов с элементами инфоблока и может быть подключен в .left.menu_ext.php. Если нужно доработать или добавить функционал, дайте знать! 😊
Добавить комментарий