Главная » Администрирование Битрикс » Инфоблоки » Разделы инфоблока: настройка и вывод дерева

Разделы инфоблока: настройка и вывод дерева

Схема дерева разделов инфоблока в Битрикс: построение одним запросом вместо рекурсивного обхода

Разделы инфоблока образуют дерево, по которому строится структура каталога, рубрики новостей или любая другая иерархия контента. Разберём, как их настраивать и выводить дерево программно — задача, которая на практике решается несколькими разными способами в зависимости от того, нужна ли полная гибкость или достаточно готового компонента.

Настройка через административную часть

Разделы создаются в разделе Контент → выбранный инфоблок → Разделы. Каждый раздел имеет название, символьный код, сортировку, привязку к родительскому разделу и, при необходимости, собственные UF-поля — например, изображение раздела или текстовое описание для страницы категории каталога.

Ограничение глубины

Формально Битрикс не ограничивает вложенность разделов, но практический предел — три-четыре уровня. Более глубокая структура усложняет навигацию для посетителя и требует более сложной логики построения меню и хлебных крошек. Если кажется, что нужно больше уровней, часто это признак того, что структуру стоит пересмотреть, а не добавлять ещё один уровень вложенности.

Нужна помощь с Битрикс?





    Вывод дерева разделов компонентом

    Для типовых случаев есть готовые компоненты, не требующие написания кода:

    <$APPLICATION->IncludeComponent(
        'bitrix:catalog.section.list',
        'main',
        [
            'IBLOCK_TYPE'    => 'catalog',
            'IBLOCK_ID'      => 5,
            'SECTION_ID'     => 0,
            'COUNT_ELEMENTS' => 'Y',
            'TOP_DEPTH'      => 2,
            'ADD_SECTIONS_CHAIN' => 'N',
            'VIEW_MODE'      => 'LINE',
        ]
    );?>

    Получение дерева из кода

    Когда готового компонента недостаточно, дерево строится напрямую через API:

    <?php
    
    use Bitrix\Main\Loader;
    
    Loader::includeModule('iblock');
    
    function getSectionTree(int $iblockId, int $parentId = 0): array
    {
        $tree = [];
    
        $result = CIBlockSection::GetList(
            ['SORT' => 'ASC'],
            [
                'IBLOCK_ID' => $iblockId,
                'ACTIVE'    => 'Y',
                'SECTION_ID' => $parentId,
            ],
            false,
            ['ID', 'NAME', 'CODE']
        );
    
        while ($section = $result->GetNext()) {
            $section['CHILDREN'] = getSectionTree($iblockId, $section['ID']);
            $tree[] = $section;
        }
    
        return $tree;
    }
    
    $tree = getSectionTree(5);

    Рекурсивная функция вызывает саму себя для каждого найденного раздела, собирая дочерние разделы вложенным массивом. На большом дереве с сотнями разделов такой подход создаёт много отдельных запросов — по одному на каждый уровень вложенности каждой ветки.

    Оптимизация: одна выборка вместо рекурсии

    Для больших деревьев эффективнее получить все разделы одним запросом и собрать иерархию уже в памяти PHP:

    <?php
    
    $result = CIBlockSection::GetList(
        ['LEFT_MARGIN' => 'ASC'],
        ['IBLOCK_ID' => 5, 'ACTIVE' => 'Y'],
        false,
        ['ID', 'NAME', 'IBLOCK_SECTION_ID']
    );
    
    $flat = [];
    while ($section = $result->GetNext()) {
        $flat[$section['ID']] = $section;
        $flat[$section['ID']]['CHILDREN'] = [];
    }
    
    $tree = [];
    foreach ($flat as $id => &$section) {
        $parentId = $section['IBLOCK_SECTION_ID'];
    
        if ($parentId && isset($flat[$parentId])) {
            $flat[$parentId]['CHILDREN'][] = &$section;
        } else {
            $tree[] = &$section;
        }
    }
    unset($section);

    Здесь один запрос к базе вместо десятков или сотен, а сборка иерархии происходит в оперативной памяти — заметно быстрее на дереве с реальным объёмом разделов, особенно в сочетании с кешированием результата.

    Сортировка LEFT_MARGIN / RIGHT_MARGIN

    Поля LEFT_MARGIN и RIGHT_MARGIN — служебная реализация дерева по методу вложенных множеств. Сортировка по LEFT_MARGIN возвращает разделы уже в правильном порядке обхода дерева, что удобно использовать вместо построения иерархии вручную, если достаточно линейного списка с отступами по уровню вложенности.

    Кеширование дерева

    Дерево разделов меняется редко по сравнению с элементами внутри него, поэтому результат построения дерева — хороший кандидат для кеширования через Bitrix\Main\Data\Cache, с тегом на инфоблок, чтобы кеш сбрасывался автоматически при добавлении или изменении раздела.

    Частые ошибки

    • Рекурсивный обход без кеширования на большом дереве. Каждый показ страницы пересчитывает структуру заново.
    • Слишком глубокая вложенность. Пять и более уровней усложняют и код, и навигацию для посетителя.
    • Не выбираются нужные поля явно. Выборка всех полей раздела вместо конкретно нужных увеличивает объём данных.
    • Игнорируется готовый компонент там, где типового вывода дерева было бы достаточно — своя реализация пишется без необходимости.

    Итог

    Разделы инфоблока настраиваются в административной части и образуют дерево, глубину которого разумно ограничивать тремя-четырьмя уровнями. Для типового вывода хватает готового компонента, а для собственной логики построение дерева одним запросом с последующей сборкой иерархии в памяти работает заметно быстрее рекурсивного обхода с запросом на каждый уровень.

    Нужна помощь с Битрикс?

    Исправим ошибку, доработаем сайт, ускорим Битрикс или поможем разобраться с проблемой.

    Услуги
    Инструменты
    База знаний