В данной статье речь пойдет о малоизвестных полях секции инфоблока 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’ов, которые понимают условие типа «неравенство»
Больше статей и материалов по web-разработке в tg-канале - подписывайтесь!
Подписаться в telegram
Алексей, хорошая информация, спасибо, именно об этом никогда не задумывался почему то. Однако показывая \»живой пример\» в виде кода, хотелось бы больше пояснений и пример результата этого кода — так будет нагляднее.
Учту, как-то не подумал об этом сразу.
А как отсортировать разделы по алфавиту не взирая на SORT?
Игорь, если вопрос в том, как функцией GetList получить список разделов, отсортированных по алфавиту — то для этого используется 1й параметр функции. Например Array(«NAME»=>»ASC») отсоритирует по названиям по возрастанию.
Доброй ночи, Алексей! Пытался использовать ваш пример, но результата не получил. Создал компонент на основе catalog.sections.list, вставил в шаблон ваш код — и ничего. Понимаю, что где-то ошибся, но не могу понять, где…
Владимир, порядок действий такой. Кидаем на страницу компонент catalog.section (можно комплексный catalog) — копируем виз. средствами шаблон компонента — в режиме редактирования шаблона компонента вставляем код
Алексей, вроде все так и сделал. Кинул на страницу свой компонент, вставил код в шаблон… Такое ощущение, что или dbSect или arSect не заполняется.
Даже не знаю тогда, надо на месте разбираться
Как человеку не любящему Битрикс, но интересующемуся Лефт Райт марджинами в структурх каталогов — ни хрена не понятно.. Если точнее — совсем чуть чуть
понятно как нумеруется… а практическое применение ? зачем они надо то эти маржины?
Интересно, кто то сможет сказать зачем они нужны?
Примеры… практические… жизненные..
Давайте давайте )
Плюс от googla не нашел, поставлю так +
Спасибо! Помогло.
Тоже ничего не выводит DESCRIPTION пустой ничего нет, информация выводится у меня только по тому где нахожусь, никакого сквозного меню или чего в массиве я не нашел.
Здравствуйте, Алексей!
В общем, ситуация такая. Имеется инфоблок «Торговый каталог» следующей структуры:
-Мебель
—Детская мебель
—Зеркала
—…
—Мягкая мебель
—Диваны
—Текстиль
—Для ванной
—Ковры
-Свет
—Напольный
—Настенный
—…
-Аксессуары
—Вешалки
—Картины
—Часы
Как сделать так, чтобы, например, если я нахожусь на какой-нибудь странице из Мебели (либо на ней самой, либо на Зеркалах, либо на Коврах) мне выводилось дерево всех подкатегорий Мебели, вложенных в Мебель. Аналогично и с другими разделами.
Спасибо!
Всегда, когда встает вопрос о left_margin и right_margin, захожу сюда.
Спасибо за статью!
интересует такой вопрос: Выводится 2 раздела, а точнее из подразделы, но сортировка происходит следующим образом сортируется вначале 1 раздел и выводится, а потом 2 как мне сделать так чтобы сортировались по 2 разделам.
Вопрос непонятен, какая именно структура выборки и как ее нужно отсортировать?
1 раздел(диваны без раскладного механизма) > в нем подразделы серий диванов (А-01, А-02, А-04); 2 раздел(диваны с раскладным механизмом) > в нем подразделы серий диванов но есть например А-03 и он выводится только после вывода 1 раздела то есть серия А не вместе. Хочу сделать сортировку для 2 разделов. Делал через component.php вместо left_margin ставил «sort» > «asc» но он глобально сортирует все, даже меню которое построено на основе компонента catalog.section.list; Как можно реализовать сортировку? Или можно создать component.php для кастомизированного шаблона, что то типа result_modifer.php
Андрей, мне кажется тут проще всего в result_modifier.php шаблона компонента отсортировать как требуется уже выбранные данные и не лезть в сам компонент.
Интересует такой вопрос, стандартное горизонтальное меню (компонент) выводит меню из разделов, хоче сделать меню из букв A B C D … и они все разделы в то что в них элементы и при наведении мне выдаетсодежримое раздела, стандартный компонент отрабает на уровне вложенности и это не трудно проверяет DEPTH_LEVEL и втыкает — ему через ксс присваиваем display: none при наведении display: block и вуаля меню сделано, Но как сделать проверку не на уровень а на наличие элементов:
??? <ul = 2):?> style=»display:none;» > ???
Спасибо, годная статья, помогла разобраться с маргинами.
Подскажите пожалуйста! допустим вывожу все товары через CIblockElement::GetList(). Мне нужно чтобы товары были отсортированы по категориям. Чтобы не было такого что товары одной категории были разбросаны по разным местам. Можно как то обойтись API битрикса не прибегая к собственной сортировке?
Вполне жизненное и полезное применение маргинов, обнаружил его случайно, копаясь в исходниках формирования меню админки каталогов. С помощью маргинов в динамическом меню определяется, есть ли у категории подкатегории (свойство dynamic):
‘dynamic’ => ($section[«RIGHT_MARGIN»] — $section[«LEFT_MARGIN»]) > 1
И вот почему-то думается, а нафига эти плсяки с бубном, когда всё решается просто через введение parent_id и связи с id потомка и родителя, а потом обходом дерева.
почему Битрикс не ищет оптимальных вариантов, а навязывает непонятные, выдуманные ими самими, решения?
Nested Set — один из стандартных методов хранения деревьев в БД. В этом случае Битрикс ничего не выдумывал:)
Дмитрий, потому что выборка по parent_id (он же Adjacency list) не эффективна в виду своей рекурсивной природы — чем больше элементов в дереве, тем дольше будет выполняться запрос. Nested Set позволяет существенно сократить нагрузку на запросы выборки, увеличивая нагрузку на запросы вставки.