Разработка модуля многоуровневого меню 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Услуги, которые мы предлагаем
Показано 1 из 1Все 1626 услуг
Разработка модуля многоуровневого меню 1С-Битрикс
Средний
~1-2 недели
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1322
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    915
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    663
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    811
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    710
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    1043

Проблемы стандартных меню и наше решение

Стандартный компонент bitrix:menu генерирует меню из файлов .menu.php или структуры сайта. Для простых сайтов этого достаточно, но когда в каталоге тысячи товаров и нужно управлять мегаменю с картинками, баннерами, колонками — начинаются тормоза. Мы разработали модуль, который решает эти проблемы: даёт гибкое управление через интерфейс с кэшированием и полной поддержкой мегаменю. Модуль подходит для проектов с любым объёмом пунктов — проверено на каталогах до 10 000 позиций.

Почему стандартный bitrix:menu не справляется с большими каталогами?

Одна из главных проблем — отсутствие тегированного кэширования. Каждый запрос перестраивает дерево из файлов, а при динамическом добавлении пунктов через административный интерфейс — невозможно. Наш модуль хранит всё в базе данных и кэширует дерево с тегом, инвалидация происходит при любом изменении. Это даёт выигрыш в скорости в 10–50 раз по сравнению с разбором файлов.

Как мы реализовали масштабируемую модель данных?

Мы использовали ORM Битрикс (таблицы b_vendor_menu_*) с adjacency list для хранения иерархии. Почему adjacency list, а не nested sets? Для меню с частыми изменениями структуры (добавление, удаление, перемещение) adjacency list быстрее на запись, а чтение с кэшем нивелирует разницу.

Модель данных

Модуль vendor.megamenu:

  • b_vendor_menu_config — конфигурации меню: id, code, name, site_id, lang, is_active
  • b_vendor_menu_item — пункты меню: id, menu_id, parent_id, sort, title, url, url_type (absolute/relative/component), target, icon_id, image_id, css_class, visibility (all/authorized/unauthorized), condition (JSON), is_active
  • b_vendor_menu_column — колонки мегаменю для пункта второго уровня: id, item_id, title, sort, items (JSON — ссылки без отдельных записей)
  • b_vendor_menu_banner — баннеры в мегаменю: id, item_id, image_id, url, title, sort

Дерево пунктов меню

Пункты хранятся в adjacency list (parent_id). Для построения дерева используется итеративный обход, чтобы избежать рекурсии в PHP:

class MenuTreeBuilder
{
    public function build(int $menuId): array
    {
        $items = MenuItemTable::getList([
            'filter' => ['MENU_ID' => $menuId, 'IS_ACTIVE' => 'Y'],
            'order'  => ['PARENT_ID' => 'ASC', 'SORT' => 'ASC'],
        ])->fetchAll();

        $tree  = [];
        $index = [];

        foreach ($items as $item) {
            $item['children'] = [];
            $index[$item['ID']] = &$item;
        }

        foreach ($index as &$item) {
            if ($item['PARENT_ID']) {
                $index[$item['PARENT_ID']]['children'][] = &$item;
            } else {
                $tree[] = &$item;
            }
        }

        return $tree;
    }
}

Дерево кешируется целиком тегом menu_{code}_{lang}. Инвалидация — при любом изменении пункта или баннера этого меню.

Видимость пунктов

Условия видимости пункта меню:

  • visibility = 'authorized' — пункт скрыт для гостей
  • visibility = 'unauthorized' — пункт скрыт для залогиненных пользователей
  • condition (JSON) — произвольные условия: группы пользователей, регион, параметры запроса
class VisibilityChecker
{
    public function isVisible(array $item): bool
    {
        global $USER;

        if ($item['VISIBILITY'] === 'authorized' && !$USER->IsAuthorized()) return false;
        if ($item['VISIBILITY'] === 'unauthorized' && $USER->IsAuthorized()) return false;

        $condition = $item['CONDITION'] ?? [];
        if (!empty($condition['user_groups'])) {
            $userGroups = $USER->GetUserGroupArray();
            if (!array_intersect($condition['user_groups'], $userGroups)) return false;
        }

        return true;
    }
}

Условия видимости применяются уже после получения кешированного дерева — кеш хранит полное дерево, фильтрация происходит в памяти.

Мегаменю с колонками и баннерами

Для пунктов верхнего уровня можно настроить мегаменю-дропдаун с колонками:

[Каталог]
├─ Колонка 1: Электроника
│   ├─ Смартфоны
│   ├─ Ноутбуки
│   └─ Планшеты
├─ Колонка 2: Бытовая техника
│   ├─ Холодильники
│   └─ Стиральные машины
└─ Баннер: [Акции недели → /sale/]

Колонки хранятся в b_vendor_menu_column, баннеры — в b_vendor_menu_banner. Компонент генерирует HTML-структуру мегаменю, стилизация — через CSS Grid.

Drag-and-drop интерфейс

Административный интерфейс построен на библиотеке Sortable.js. Пункты перетаскиваются в нужную позицию и в нужный родительский элемент. При перетаскивании AJAX-запрос обновляет sort и parent_id одной транзакцией.

Активный пункт

Активный пункт меню определяется по текущему URL:

// Точное совпадение URL или совпадение начала пути
function isActive(array $item, string $currentUrl): bool
{
    if ($item['URL'] === $currentUrl) return true;
    if ($item['URL_TYPE'] === 'section' && str_starts_with($currentUrl, $item['URL'])) return true;
    return false;
}

Активный пункт и все его предки получают CSS-класс active.

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

Критерий Стандартный bitrix:menu Наш модуль
Управление из админки Только через файлы Через визуальный drag-and-drop
Мегаменю Требует ручной разметки Встроенные колонки и баннеры
Кэширование Файловое, без тегов Тегированное, инвалидация по событиям
Видимость по группам Только через условие в файле Интерфейс + произвольные условия
Срок внедрения 2-3 дня на настройку 10 дней под ключ

Процесс работы

Мы проходим все этапы от анализа до внедрения:

  1. Аналитика — изучаем структуру каталога, требования к видимости, интеграции.
  2. Проектирование — схемы БД, прототип дерева, согласование с заказчиком.
  3. Разработка — создание ORM-модуля, компонентов, интерфейса админки.
  4. Тестирование — проверка на реальных данных, нагрузочное тестирование.
  5. Внедрение — установка на боевом сайте, настройка кэширования, обучение контент-менеджеров.

Что вы получаете в итоге?

  • Модуль с ORM-таблицами, компонентом для вывода меню, административным интерфейсом.
  • Документация по настройке и использованию.
  • Исходные коды в репозитории.
  • Техническая поддержка в течение 30 дней после запуска.

Сроки разработки

Этап Срок
ORM-таблицы, модель дерева 1 день
Построение дерева, кеширование 1 день
Условия видимости пунктов 1 день
Мегаменю: колонки, баннеры 2 дня
Drag-and-drop интерфейс 2 дня
Компоненты для сайта (HTML + CSS) 2 дня
Тестирование 1 день

Итого: от 10 до 15 рабочих дней в зависимости от сложности.

Оптимизация скорости менюДля ускорения загрузки используйте тегированное кэширование: компонент кэшируется на 3600 секунд с тегом `menu_{code}`. При любом изменении пункта или баннера кэш сбрасывается автоматически через агент. Для больших каталогов (10 000+) рекомендуем включить композитный кэш Битрикс и настроить отложенную загрузку меню через `Bitrix\Main\Page\FrameStatic`.

Подход adjacency list описан в статье Список смежности. Стилизация мегаменю выполняется с помощью CSS Grid.

Наш опыт разработки модулей Битрикс — более 7 лет. Выполнили 50+ проектов по созданию кастомных решений. Гарантируем соблюдение сроков и качество. Свяжитесь с нами для оценки вашей задачи за один день — мы подготовим оптимальное решение. Получите консультацию по проекту: просто напишите нам, и мы обсудим детали.