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

Проблеми стандартних меню та наше рішення Стандартний компонент `bitrix:menu` генерує меню з файлів `.menu.php` або структури сайту. Для простих сайтів цього достатньо, але коли в каталозі тисячі товарів і потрібно керувати мегаменю з картинками, банерами, колонками — починаються гальма. Ми розро
Послуги, які ми пропонуємо
Показано 1 з 1Усі 1626 послуг
Розробка модуля багаторівневого меню для 1С-Бітрікс
Середній
~1-2 тижні

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

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1454
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Розробка веб-сайту для компанії ФІКСПЕР
    1018
  • 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
    760
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    879
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    803
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    1162

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

Стандартний компонент 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+ проєктів зі створення кастомних рішень. Гарантуємо дотримання термінів та якість. Зв'яжіться з нами для оцінки вашого завдання за один день — ми підготуємо оптимальне рішення. Отримайте консультацію з проєкту: просто напишіть нам, і ми обговоримо деталі.