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

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Разработка модуля многоуровневого меню 1С-Битрикс
Средняя
~1-2 недели
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1177
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • 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
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    747
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

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

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

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

Модуль 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.

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

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

Итого: 10 рабочих дней. Для мобильного меню (offcanvas, hamburger) — дополнительно 1 день.