Разделы инфоблоков Битрикс — используем архитектурные особенности

В данной статье речь пойдет о малоизвестных полях секции инфоблока left- и right-margin, которые позволяют одним вызовом функции CIBlockSection::GetList получить практически любую информацию о вложенных\родительских разделах. Для начала пробежимся по теоретической части, а когда все станет ясно с алгоритмом заполнения этих полей, приведем конкретный пример использования.

Сортировка и представление данных

Каждый раздел в системе Битрикс имеет несколько параметров, влияющих на его положение в дереве. В первую очередь это поле SORT, которое можно заполнить при создании или редактировании. Оно влияет на сортировку разделов одного уровня вложенности относительно единого родителя. Уровень вложенности всегда можно узнать из поля DEPTH_LEVEL (=1 для корневых разделов, =2 для первого уровня вложенности и т.д.). Таким образом, поле SORT используется для «локальной» сортировки.

Продемонстрировать процедуру определения значений параметров left- и right-margin поможет рисунок ниже

Цифры слева от разделов — это left-margin, справа — right-margin. Начиная от самого верхнего уровня (с наименьшим SORT) последовательно вписываем значения left-margin, заходя во все подразделы, пока не встретится один из случаев:
1. у раздела нет потомков, но есть нижестоящие категории с одинаковым уровнем вложенности (DEPTH_LEVEL), в примере «b», «d», «g». В этом случае вписываем для раздела right-margin=left-margin+1 и двигаемся дальше вниз по левой стороне.
2. у раздела нет потомков и вложенных\нижестоящих узлов — «e», «f», «i». Для него также right-margin=left-margin+1 и дальнейшее движение идет вверх по правой стороне. Уже заполненные значения пропускаем (правое число для «b», «d», «g» при движении вверх)

Практическое применение

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

CModule::IncludeModule('iblock');
$dbSect = CIBlockSection::GetList(Array("SORT"=>"ASC"), Array("IBLOCK_ID"=>$arResult["IBLOCK_ID"], "<=LEFT_BORDER" => $arResult["LEFT_MARGIN"], ">=RIGHT_BORDER" => $arResult["RIGHT_MARGIN"], "DEPTH_LEVEL" => 1), false); 
if($arSect = $dbSect->GetNext()) {echo $arSect["DESCRIPTION"];}

LEFT_BORDER и RIGHT_BORDER — аналоги margin’ов, которые понимают условие типа «неравенство»

Если вам понравилась статья, подписывайтесь на обновления блога по rss или присоединяйтесь в twitter

Поделиться ссылкой с друзьями:

Метки: ,

Категории: Bitrix

Комментарии (25)

  1. Алексей, хорошая информация, спасибо, именно об этом никогда не задумывался почему то. Однако показывая \»живой пример\» в виде кода, хотелось бы больше пояснений и пример результата этого кода — так будет нагляднее.

  2. Учту, как-то не подумал об этом сразу.

  3. Игорь:

    А как отсортировать разделы по алфавиту не взирая на SORT?

  4. Игорь, если вопрос в том, как функцией GetList получить список разделов, отсортированных по алфавиту — то для этого используется 1й параметр функции. Например Array(«NAME»=>»ASC») отсоритирует по названиям по возрастанию.

  5. Владимир:

    Доброй ночи, Алексей! Пытался использовать ваш пример, но результата не получил. Создал компонент на основе catalog.sections.list, вставил в шаблон ваш код — и ничего. Понимаю, что где-то ошибся, но не могу понять, где…

  6. Владимир, порядок действий такой. Кидаем на страницу компонент catalog.section (можно комплексный catalog) — копируем виз. средствами шаблон компонента — в режиме редактирования шаблона компонента вставляем код

  7. Владимир:

    Алексей, вроде все так и сделал. Кинул на страницу свой компонент, вставил код в шаблон… Такое ощущение, что или dbSect или arSect не заполняется.

  8. Даже не знаю тогда, надо на месте разбираться

  9. Как человеку не любящему Битрикс, но интересующемуся Лефт Райт марджинами в структурх каталогов — ни хрена не понятно.. Если точнее — совсем чуть чуть

  10. понятно как нумеруется… а практическое применение ? зачем они надо то эти маржины?

  11. Интересно, кто то сможет сказать зачем они нужны?
    Примеры… практические… жизненные..
    Давайте давайте )

  12. tirei_01:

    Плюс от googla не нашел, поставлю так +
    Спасибо! Помогло.

  13. Никита:

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

  14. Здравствуйте, Алексей!

    В общем, ситуация такая. Имеется инфоблок «Торговый каталог» следующей структуры:

    -Мебель
    —Детская мебель
    —Зеркала
    —…
    —Мягкая мебель
    —Диваны
    —Текстиль
    —Для ванной
    —Ковры
    -Свет
    —Напольный
    —Настенный
    —…
    -Аксессуары
    —Вешалки
    —Картины
    —Часы

    Как сделать так, чтобы, например, если я нахожусь на какой-нибудь странице из Мебели (либо на ней самой, либо на Зеркалах, либо на Коврах) мне выводилось дерево всех подкатегорий Мебели, вложенных в Мебель. Аналогично и с другими разделами.

    Спасибо!

  15. Эдуард:

    Всегда, когда встает вопрос о left_margin и right_margin, захожу сюда.
    Спасибо за статью!

  16. Андрей:

    интересует такой вопрос: Выводится 2 раздела, а точнее из подразделы, но сортировка происходит следующим образом сортируется вначале 1 раздел и выводится, а потом 2 как мне сделать так чтобы сортировались по 2 разделам.

  17. Алексей Валеев:

    Вопрос непонятен, какая именно структура выборки и как ее нужно отсортировать?

  18. Андрей:

    1 раздел(диваны без раскладного механизма) > в нем подразделы серий диванов (А-01, А-02, А-04); 2 раздел(диваны с раскладным механизмом) > в нем подразделы серий диванов но есть например А-03 и он выводится только после вывода 1 раздела то есть серия А не вместе. Хочу сделать сортировку для 2 разделов. Делал через component.php вместо left_margin ставил «sort» > «asc» но он глобально сортирует все, даже меню которое построено на основе компонента catalog.section.list; Как можно реализовать сортировку? Или можно создать component.php для кастомизированного шаблона, что то типа result_modifer.php

  19. Алексей Валеев:

    Андрей, мне кажется тут проще всего в result_modifier.php шаблона компонента отсортировать как требуется уже выбранные данные и не лезть в сам компонент.

  20. Андрей:

    Интересует такой вопрос, стандартное горизонтальное меню (компонент) выводит меню из разделов, хоче сделать меню из букв A B C D … и они все разделы в то что в них элементы и при наведении мне выдаетсодежримое раздела, стандартный компонент отрабает на уровне вложенности и это не трудно проверяет DEPTH_LEVEL и втыкает — ему через ксс присваиваем display: none при наведении display: block и вуаля меню сделано, Но как сделать проверку не на уровень а на наличие элементов:
    ??? <ul = 2):?> style=»display:none;» > ???

  21. Спасибо, годная статья, помогла разобраться с маргинами.

  22. Подскажите пожалуйста! допустим вывожу все товары через CIblockElement::GetList(). Мне нужно чтобы товары были отсортированы по категориям. Чтобы не было такого что товары одной категории были разбросаны по разным местам. Можно как то обойтись API битрикса не прибегая к собственной сортировке?

  23. HEKET313:

    Вполне жизненное и полезное применение маргинов, обнаружил его случайно, копаясь в исходниках формирования меню админки каталогов. С помощью маргинов в динамическом меню определяется, есть ли у категории подкатегории (свойство dynamic):
    ‘dynamic’ => ($section["RIGHT_MARGIN"] — $section["LEFT_MARGIN"]) > 1

  24. Дмитрий:

    И вот почему-то думается, а нафига эти плсяки с бубном, когда всё решается просто через введение parent_id и связи с id потомка и родителя, а потом обходом дерева.
    почему Битрикс не ищет оптимальных вариантов, а навязывает непонятные, выдуманные ими самими, решения?

  25. Алексей Валеев:

    Nested Set — один из стандартных методов хранения деревьев в БД. В этом случае Битрикс ничего не выдумывал:)

Оставить комментарий