Блог разработчика 1С-Битрикс

Вывод разделов и элементов с учетом вложенности в .left.menu_ext.php для 1С-Битрикс

В 1С-Битрикс для вывода структуры инфоблока, включая разделы и элементы, в файле .left.menu_ext.php можно воспользоваться следующей логикой. В данном случае мы предполагаем, что необходимо получить названия и ссылки как для разделов, так и для элементов инфоблока с определённым ID.

Вывод разделов и элементов для .left.menu_ext.php

Вывод разделов и элементов без учета вложенности

Пример кода для файла .left.menu_ext.php

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

// ID инфоблока
$iblockId = 1;

$menuLinks = [];

// Подключаем модуль инфоблоков
if (CModule::IncludeModule('iblock')) {
    // 1. Получаем список разделов инфоблока
    $sections = CIBlockSection::GetList(
        ['LEFT_MARGIN' => 'ASC'], // Сортировка
        ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'], // Условия фильтрации
        false, // Не группируем
        ['ID', 'NAME', 'SECTION_PAGE_URL'] // Какие поля загружаем
    );

    while ($section = $sections->GetNext()) {
        $menuLinks[] = [
            $section['NAME'],                 // Название раздела
            $section['SECTION_PAGE_URL'],     // Ссылка на раздел
            [],                               // Дополнительные параметры (например, иконки)
            ['FROM_IBLOCK' => true, 'IS_PARENT' => true], // Статус (раздел - родительский элемент)
            ''                                // Условие активности
        ];
    }

    // 2. Получаем список элементов инфоблока
    $elements = CIBlockElement::GetList(
        ['SORT' => 'ASC'], // Сортировка
        ['IBLOCK_ID' => $iblockId, 'ACTIVE' => 'Y'], // Условия фильтрации
        false, // Не группируем
        false, // Постраничная навигация
        ['ID', 'NAME', 'DETAIL_PAGE_URL', 'IBLOCK_SECTION_ID'] // Какие поля загружаем
    );

    while ($element = $elements->GetNext()) {
        $menuLinks[] = [
            $element['NAME'],               // Название элемента
            $element['DETAIL_PAGE_URL'],    // Ссылка на элемент
            [],                             // Дополнительные параметры
            ['FROM_IBLOCK' => true],        // Статус
            ''                              // Условие активности
        ];
    }
}

// Возвращаем массив $menuLinks
$aMenuLinks = $menuLinks;

Пояснения к коду

  1. Подключение модуля: Мы используем CModule::IncludeModule('iblock') для работы с инфоблоками. Убедитесь, что модуль "Инфоблоки" установлен.
  2. Секции (разделы): Используется класс CIBlockSection для получения списка разделов инфоблока. Поле SECTION_PAGE_URL автоматически формируется на основе настроек инфоблока.
  3. Элементы: Используется класс CIBlockElement для получения элементов инфоблока. Поле DETAIL_PAGE_URL также формируется автоматически.
  4. Форматирование массива: Формируется массив $menuLinks в формате, принятом для меню в Битриксе.

Настройки инфоблока

Для корректного формирования ссылок (SECTION_PAGE_URL и DETAIL_PAGE_URL) убедитесь, что в настройках инфоблока у вас правильно заданы шаблоны URL:

  • URL страницы раздела: #SITE_DIR#catalog/#SECTION_CODE_PATH#/
  • URL страницы элемента: #SITE_DIR#catalog/#SECTION_CODE_PATH#/#ELEMENT_CODE#/

Что делать, если нужно учитывать вложенность?

Если требуется учитывать вложенность элементов (расположение элементов в разделах), можно добавить соответствующую логику: элементы будут добавляться только к своим родительским разделам.

Пример для вложенной структуры:

$menuLinks[$sectionId][] = [...]; // Привязка элемента к родительскому разделу

Для вывода всех разделов и элементов инфоблока с учётом их вложенности в структуру, используем API CIBlockSection и CIBlockElement. Основная идея заключается в том, чтобы сначала получить дерево разделов заданного инфоблока, а затем для каждого раздела получить элементы. Следующий пример кода предназначен для использования в файле .left.menu_ext.php в Битриксе:

Решение

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

// ID нужного инфоблока
$IBLOCK_ID = 1;

// Подключаем модуль инфоблоков
CModule::IncludeModule('iblock');

// Функция для получения разделов и элементов с их вложенностью
function getSectionsWithElements($iblockId) {
    $result = [];

    // Получаем разделы инфоблока
    $sectionFilter = [
        'IBLOCK_ID' => $iblockId,
        'ACTIVE' => 'Y'
    ];
    $sectionSelect = ['ID', 'NAME', 'SECTION_PAGE_URL', 'DEPTH_LEVEL'];
    $sections = CIBlockSection::GetList(
        ['LEFT_MARGIN' => 'ASC'], // Сортировка по иерархии разделов
        $sectionFilter,
        false,
        $sectionSelect
    );

    while ($section = $sections->GetNext()) {
        $result[$section['ID']] = [
            'NAME' => $section['NAME'],
            'URL' => $section['SECTION_PAGE_URL'],
            'DEPTH_LEVEL' => $section['DEPTH_LEVEL'],
            'ELEMENTS' => []
        ];
    }

    // Получаем элементы инфоблока
    $elementFilter = [
        'IBLOCK_ID' => $iblockId,
        'ACTIVE' => 'Y'
    ];
    $elementSelect = ['ID', 'IBLOCK_SECTION_ID', 'NAME', 'DETAIL_PAGE_URL'];
    $elements = CIBlockElement::GetList(
        ['SORT' => 'ASC'], // Сортировка элементов
        $elementFilter,
        false,
        false,
        $elementSelect
    );

    while ($element = $elements->GetNext()) {
        if (isset($result[$element['IBLOCK_SECTION_ID']])) {
            $result[$element['IBLOCK_SECTION_ID']]['ELEMENTS'][] = [
                'NAME' => $element['NAME'],
                'URL' => $element['DETAIL_PAGE_URL']
            ];
        }
    }

    return $result;
}

// Получаем данные о разделах и элементах
$sectionsWithElements = getSectionsWithElements($IBLOCK_ID);

// Генерация массива данных для меню
$aMenuLinksExt = [];

foreach ($sectionsWithElements as $section) {
    $aMenuLinksExt[] = [
        $section['NAME'],
        $section['URL'],
        [],
        ['DEPTH_LEVEL' => $section['DEPTH_LEVEL']],
        ""
    ];

    foreach ($section['ELEMENTS'] as $element) {
        $aMenuLinksExt[] = [
            $element['NAME'],
            $element['URL'],
            [],
            ['DEPTH_LEVEL' => $section['DEPTH_LEVEL'] + 1],
            ""
        ];
    }
}


// Добавляем сгенерированные ссылки в основное меню
$aMenuLinks = array_merge($aMenuLinks, $aMenuLinksExt);
?>

Пояснение коду

  1. Получение разделов:

    • Используется метод CIBlockSection::GetList(), чтобы собрать разделы инфоблока.
    • Сортировка по LEFT_MARGIN позволяет получить разделы в иерархическом порядке.
    • В результат добавляются NAME, URL и уровень вложенности DEPTH_LEVEL.
  2. Получение элементов:

    • Используется метод CIBlockElement::GetList() для получения активных элементов инфоблока.
    • Элементы группируются внутри своих разделов с помощью ID раздела (IBLOCK_SECTION_ID).
  3. Формирование меню:

    • Все разделы добавляются в массив $aMenuLinksExt с учётом уровня вложенности (DEPTH_LEVEL).
    • Элементы добавляются как вложенные пункты (уровень вложенности увеличен на 1).
  4. Вывод в меню:

    • Итоговый массив $aMenuLinksExt объединяется с меню $aMenuLinks (по умолчанию подключаемое в файлах .menu_ext.php).

Результат

Когда вы добавите данный код в файл .left.menu_ext.php, меню будет формироваться динамически на основе структуры разделов и элементов инфоблока. Будут учитываться как разделы, так и вложенные в них элементы.

Если у вас настраивается "Карта сайта", этот подход позволяет автоматически обновлять содержимое при изменении в админке инфоблока (добавление/удаление разделов и элементов).

Теги: .left.menu_ext.php, вывод меню, вложенность меню, разделы и элементы, настройка меню, разработка на Битрикс, динамическое меню, структура сайта, программирование в Битрикс


Валерий Макеев
09.09.2025 16:29
Этот код создает иерархическое меню разделов и элементов инфоблока с сохранением структуры вложенности для использования в компонентах меню Битрикс.
Код
<?php
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

$IBLOCK_ID = 5;

if (!CModule::IncludeModule('iblock')) {
    return;
}

$aMenuLinks = [];

// Получение разделов
$allSections = [];
$rsSections = CIBlockSection::GetList(
    ['LEFT_MARGIN' => 'ASC'],
    ['IBLOCK_ID' => $IBLOCK_ID, 'ACTIVE' => 'Y'],
    false,
    ['ID', 'NAME', 'SECTION_PAGE_URL', 'DEPTH_LEVEL', 'IBLOCK_SECTION_ID']
);
while ($section = $rsSections->GetNext()) {
    $section['CHILDREN'] = [];
    $section['ELEMENTS'] = [];
    $allSections[$section['ID']] = $section;
}

// Построение дерева
$sectionTree = [];
foreach ($allSections as $id => $section) {
    $parentId = $section['IBLOCK_SECTION_ID'];
    if ($parentId > 0 && isset($allSections[$parentId])) {
        $allSections[$parentId]['CHILDREN'][$id] = &$allSections[$id];
    } else {
        $sectionTree[$id] = &$allSections[$id];
    }
}

// Получение элементов
$rsElements = CIBlockElement::GetList(
    ['SORT' => 'ASC'],
    ['IBLOCK_ID' => $IBLOCK_ID, 'ACTIVE' => 'Y'],
    false,
    false,
    ['ID', 'NAME', 'DETAIL_PAGE_URL', 'IBLOCK_SECTION_ID']
);
while ($element = $rsElements->GetNext()) {
    $sectionId = $element['IBLOCK_SECTION_ID'];
    if (isset($allSections[$sectionId])) {
        $allSections[$sectionId]['ELEMENTS'][] = [
            'NAME' => $element['NAME'],
            'URL'  => $element['DETAIL_PAGE_URL']
        ];
    }
}

// Построение меню (с вложенными подпунктами)
function buildMenuTree($tree) {
    $menu = [];
    foreach ($tree as $section) {
        $subMenu = [];

        // Элементы раздела
        foreach ($section['ELEMENTS'] as $element) {
            $subMenu[] = [
                $element['NAME'],
                $element['URL'],
                [],
                ['DEPTH_LEVEL' => $section['DEPTH_LEVEL'] + 1],
                ''
            ];
        }

        // Подразделы
        if (!empty($section['CHILDREN'])) {
            $subMenu = array_merge($subMenu, buildMenuTree($section['CHILDREN']));
        }

        $menu[] = [
            $section['NAME'],
            $section['SECTION_PAGE_URL'],
            $subMenu,
            ['DEPTH_LEVEL' => $section['DEPTH_LEVEL']],
            ''
        ];
    }
    return $menu;
}

$aMenuLinks = buildMenuTree($sectionTree);
?>


Возможное улучшение: кеширование (если критична производительность)
Код
$obCache = new CPHPCache();
$cacheTime = 3600; // 1 час
$cacheDir = '/menu_cache/iblock_' . $IBLOCK_ID;

if ($obCache->InitCache($cacheTime, '', $cacheDir)) {
    $aMenuLinks = $obCache->GetVars();
} else {
    if ($obCache->StartDataCache()) {
        // ... весь код построения меню (от получения разделов до buildMenuTree)
        $aMenuLinks = buildMenuTree($sectionTree);
        $obCache->EndDataCache($aMenuLinks);
    } else {
        // fallback, если кеш не удалось создать
        $aMenuLinks = [];
    }
}

Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Лечение сайтов от вирусов

восстановление сайта и подъем версии PHP

от 25 000 рублей
Лечение сайтов на решениях АСПРО и прочих.

* полный комплекс лечения проекта и закрытия дыр

Разработка интернет-магазина с готовой версткой

от 4 недель

от 90 000 рублей

* указана минимальная стоимость. Стоимость выбранной лицензии «1С-Битрикс» оплачивается отдельно.

Перенос сайтов на «1С-Битрикс»

сайты на платформе «1С-Битрикс» — это удобство, надежность и высокая посещаемость

от 12 000 рублей
Перенос сайтов с любых CMS и статичных страниц на платформу «1С-Битрикс», с учетом дизайна, верстки и урл-адресов. С сохранением всей информации и структуры сайта.

* зависит от объема выполняемых работ.