EN EN

Многоуровневое меню из разделов, подразделов и элементов (bitrix:catalog)

Подробное описание по созданию меню из разделов и элементов конкретного информационного блока (инфоблока) в 1С-Битрикс

⬅️ Вернуться к статьям
Дата публикации AccelLoad
20 июня 2022
Количество просмотров AccelLoad
195
Теги AccelLoad
1С-Битрикс
bitrix:menu
Многоуровневое меню из разделов, подразделов и элементов (bitrix:catalog)

Сегодня мы подробно и по шагам расскажем, как создать многоуровневый список из разделов, подразделов и элементов этих разделов и подразделов на сайте под управлением CMS 1С-Битрикс: Управление сайтом. В качестве примера возьмём инфоблок который выведет нам дерево разделов и элементов каталога, где при наведении на последний элемент мы получим ссылку вида: https://site.ru/catalog/razdel-1-urovnya/razdel-2-urovnya/element-razdela-2-urovnya/.

Новый тип меню

1. Необходимо создать новый тип меню как показано на скрине ниже:

Дерево разделов и элементов каталога

.parameters.php

2. Создать свой компонент в своём пространстве имён и назвать его например menu.sections.elements, чтобы путь до папки получился: /local/components/accelload/menu.sections.elements/ и в нём создать файл .parameters.php, чтобы путь до файла получился: /local/components/accelload/menu.sections.elements/.parameters.php со следующим содержимым:


<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();

if(!CModule::IncludeModule("iblock"))
	return;

$arTypesEx = CIBlockParameters::GetIBlockTypes(Array("all"=>" "));

$arIBlocks=Array();
$db_iblock = CIBlock::GetList(Array("SORT"=>"ASC"), Array("SITE_ID"=>$_REQUEST["site"], "TYPE" => ($arCurrentValues["IBLOCK_TYPE"]!="all"?$arCurrentValues["IBLOCK_TYPE"]:"")));
while($arRes = $db_iblock->Fetch())
	$arIBlocks[$arRes["ID"]] = $arRes["NAME"];

$arComponentParameters = array(
	"GROUPS" => array(
	),
	"PARAMETERS" => array(
		"IBLOCK_TYPE" => Array(
			"PARENT" => "BASE",
			"NAME"=>GetMessage("CP_BMS_IBLOCK_TYPE"),
			"TYPE"=>"LIST",
			"VALUES"=>$arTypesEx,
			"DEFAULT"=>"catalog",
			"ADDITIONAL_VALUES"=>"N",
			"REFRESH" => "Y",
		),
		"IBLOCK_ID" => Array(
			"PARENT" => "BASE",
			"NAME"=>GetMessage("CP_BMS_IBLOCK_ID"),
			"TYPE"=>"LIST",
			"VALUES"=>$arIBlocks,
			"DEFAULT"=>'1',
			"MULTIPLE"=>"N",
			"ADDITIONAL_VALUES"=>"N",
			"REFRESH" => "Y",
		),
		"DEPTH_LEVEL" => Array(
			"PARENT" => "DATA_SOURCE",
			"NAME" => GetMessage("CP_BMS_DEPTH_LEVEL"),
			"TYPE" => "STRING",
			"DEFAULT" => "1",
		),
		"CACHE_TIME"  =>  Array("DEFAULT"=>36000000),
	),
);
?>

component.php

3. В этом же только что созданном компоненте создаём ещё один файл component.php, чтобы путь до файла получился: /local/components/accelload/menu.sections.elements/component.php со следующим содержимым:


<?
if (!function_exists('createMenuArray')){
	function createMenuArray(&$res,&$menuItems,$arParent,$depthLevel){
		foreach($arParent as $item){
			$isParent = ($item['IS_SECTION']&&isset($menuItems[$item['ID']]));
			$res[] = array(
				htmlspecialchars($item['~NAME']),
				$item['LINK'],
				array(),
				array(
					'FROM_IBLOCK' => true,
					'IS_PARENT' => $isParent,
					'DEPTH_LEVEL' => $depthLevel,
					'IS_SECTION' => $item['IS_SECTION'],
				),
			);
			if ($isParent){
				createMenuArray($res,$menuItems,$menuItems[$item['ID']],$depthLevel+1);
			}
		}
	}
}
if(!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED!==true) die();

if(!isset($arParams['CACHE_TIME']))
	$arParams['CACHE_TIME'] = 36000000;

$arParams['IBLOCK_ID'] = intval($arParams['IBLOCK_ID']);

$arParams['DEPTH_LEVEL'] = intval($arParams['DEPTH_LEVEL']);
if($arParams['DEPTH_LEVEL']<=0)
	$arParams['DEPTH_LEVEL']=1;

if($this->StartResultCache()) {
	CModule::IncludeModule('iblock');
	$arSectionId = array();
	$arFilter = array(
		'IBLOCK_ID'=>$arParams['IBLOCK_ID'],
		'GLOBAL_ACTIVE'=>'Y',
		'ACTIVE'=>'Y',
		'<=DEPTH_LEVEL' => $arParams['DEPTH_LEVEL'],
	);
	$arOrder = array(
		'SORT'=>'ASC',
	);
	$rsSections = CIBlockSection::GetList($arOrder, $arFilter, false, array(
		'ID',
		'DEPTH_LEVEL',
		'NAME',
		'SECTION_PAGE_URL',
		'IBLOCK_SECTION_ID',
	));
	$menuItems = array();
	while($arSection = $rsSections->GetNext()){
		$arSection['IS_SECTION'] = 1;
		$arSection['LINK'] = $arSection['SECTION_PAGE_URL'];
		if ($arSection['IBLOCK_SECTION_ID']){
			$menuItems[$arSection['IBLOCK_SECTION_ID']][] = $arSection;
		} else {
			$menuItems['ROOT'][] = $arSection;
		}
		$arSectionId[] = $arSection['ID'];
	}
	$arSelect = Array('ID', 'NAME','DETAIL_PAGE_URL', 'IBLOCK_SECTION_ID');
	$arFilter = Array(
		'IBLOCK_ID' => $arParams['IBLOCK_ID'],
		'ACTIVE' => 'Y',
		array(
			'LOGIC' => 'OR',
			array('SECTION_ID' => $arSectionId),
			array('SECTION_ID' => false),
		),
	);
	$arOrder = Array('SORT' => 'ASC');
	$res = CIBlockElement::GetList($arOrder, $arFilter, false, false, $arSelect);  
	while ($ob = $res->GetNextElement()){
		$arFields = $ob->GetFields();
		$arFields['IS_SECTION'] = 0;
		$arFields['LINK'] = $arFields['DETAIL_PAGE_URL'];
		if ($arFields['IBLOCK_SECTION_ID']){
			$menuItems[$arFields['IBLOCK_SECTION_ID']][] = $arFields;
		} else {
			$menuItems['ROOT'][] = $arFields;
		}
	}
	$arResult = array();
	createMenuArray($arResult,$menuItems,$menuItems['ROOT'],1);
	$this->EndResultCache();
}
return $arResult;
?>

.catalog.menu.php

4. В корне сайта, где лежат файлы index.php и .htaccess создаём файл .catalog.menu.php со следующим содержимым:


<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();

global $APPLICATION;

$aMenuLinksExt=$APPLICATION->IncludeComponent(
	"accelload:menu.sections.elements",
	"",
	array(
		"IBLOCK_TYPE" => "catalog",
		"IBLOCK_ID" => "21",
		"DEPTH_LEVEL" => "3",
		"CACHE_TYPE" => "A",
		"CACHE_TIME" => "36000000"
	),
	false
);
$aMenuLinks = array_merge($aMenuLinksExt, $aMenuLinks);
?>

Вместо значений catalog и 21, у вас должны быть свои параметры, TYPE (тип) и ID (айди) того инфоблока из которого будет построено ваше дерево.

bitrix:menu

5. Добавляем стандартный компонент bitrix:menu с собственным шаблоном в необходимый индексный файл вашего раздела. У нас путь до индексного файла получился: catalog/index.php со следующим содержимым:


<?
$APPLICATION->IncludeComponent(
"bitrix:menu", 
"accelload", 
array(
	"ROOT_MENU_TYPE" => "catalog",
	"MAX_LEVEL" => "3",
	"CHILD_MENU_TYPE" => "catalog",
	"USE_EXT" => "N",
	"DELAY" => "N",
	"ALLOW_MULTI_SELECT" => "N",
	"MENU_CACHE_TYPE" => "N",
	"MENU_CACHE_TIME" => "3600",
	"MENU_CACHE_USE_GROUPS" => "Y",
	"MENU_CACHE_GET_VARS" => array(
	),
	"COMPONENT_TEMPLATE" => "accelload"
),
false
?>

Результат

6. Чтобы получить такой же вид дерева разделов и элементов как на скрине ниже, вы можете скачать архив по ссылке ниже со всеми папками и файлами о которых мы упоминали в данной статье.

Многоуровневое меню из разделов, подразделов и элементов (bitrix:catalog) Скачать исходные файлы
Скролл вверх