Меню и хлебные крошки в 1С-Битрикс
Меню в 1С-Битрикс устроено непривычно: пункты хранятся не в базе, а в файлах внутри папок разделов, и наследуются вверх по структуре сайта. Разберём эту механику, динамические меню из инфоблоков и настройку хлебных крошек.
Как это работает
Тип меню - это просто имя набора пунктов. Идентификатор латиницей: top,
left, bottom. Задаётся в настройках модуля управления структурой и никак не
привязан к расположению на странице - где выводить, решает шаблон.
На каждый тип приходится два файла в папке раздела. Файл .<тип>.menu.php
содержит статическое меню - PHP-массив $aMenuLinks, который правят вручную.
Файл .<тип>.menu_ext.php строит пункты кодом, например из разделов инфоблока.
Они могут существовать одновременно.
Пункт меню - это массив из пяти элементов: название, ссылка, массив дополнительных ссылок для подсветки активности, массив дополнительных параметров и условие показа в виде PHP-выражения, которое должно вернуть истину.
Наследование идёт вверх и останавливается на первом найденном файле. Система ищет файл меню в текущем разделе, затем в родительском, затем в корне - и берёт первый найденный независимо от его содержимого. Отсюда неочевидное следствие: пустой файл меню в подразделе переопределяет родительское меню как пустое, и меню просто исчезает. Ещё одна тонкость: статическое меню заменяется только статическим, динамическое - только динамическим.
Компонент bitrix:menu читает файлы и отдаёт шаблону массив пунктов. У
каждого пункта есть TEXT, LINK, SELECTED (пользователь находится на этой
странице), ITEM_TYPE (раздел, страница или страница с параметрами), PARAMS и
PERMISSION. Стандартные шаблоны поддерживают до четырёх уровней вложенности.
Навигационная цепочка выводится компонентом bitrix:breadcrumb, который
ставят в шаблон сайта, чтобы он был на всех страницах. Текст пункта берётся из
заголовка раздела, а для элементов инфоблока - из названия. Произвольный пункт
добавляют из кода.
Примеры
1. Статическое меню
<?$aMenuLinks = Array( Array( "Новости", "news/", Array(), // дополнительные ссылки для подсветки Array(), // дополнительные параметры "CSite::InDir('/index.php')" // условие показа ), Array( "Профиль", "profile.php", Array(), Array(), "\$GLOBALS['USER']->IsAuthorized()" ),);?>Пункт «Профиль» увидят только авторизованные пользователи. Условие - это строка
с PHP-выражением, которую вычисляет компонент меню; кроме проверки авторизации
часто используют CSite::InDir() для конкретного раздела и CSite::InGroup()
для групп пользователей.
2. Динамическое меню из разделов инфоблока
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();global $APPLICATION;
$aMenuLinksExt = $APPLICATION->IncludeComponent( "bitrix:menu.sections", "", Array( "ID" => (int)($_REQUEST["ELEMENT_ID"] ?? 0), // приводим ввод к числу "IBLOCK_TYPE" => "books", "IBLOCK_ID" => "30", "SECTION_URL" => "/e-store/books/index.php?SECTION_ID=#ID#", "CACHE_TIME" => "3600", ));
$aMenuLinks = array_merge($aMenuLinks, $aMenuLinksExt);?>Три обязательных элемента такого файла: защита от прямого вызова в начале,
объявление global $APPLICATION и слияние результата со статическими пунктами в
конце. И четвёртое, не в файле: в параметрах компонента bitrix:menu должна быть
включена опция подключения файлов menu_ext.php - без неё динамические пункты
просто не появятся.
Шаблон адреса раздела берут из настроек инфоблока: без человекопонятных адресов
это вид /catalog/index.php?SECTION_ID=#ID#, с ними - /catalog/#SECTION_CODE#/.
3. Свой шаблон меню
<?php if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die(); ?><ul class="nav"><?php foreach ($arResult as $arItem): ?> <li class="<?= $arItem['SELECTED'] ? 'active' : '' ?>"> <a href="<?= $arItem['LINK'] ?>"><?= $arItem['TEXT'] ?></a> </li><?php endforeach; ?></ul>Шаблон копируют в шаблон сайта, в папку
/local/templates/<шаблон>/components/bitrix/menu/<имя>/, и правят копию.
Разметку можно менять полностью; активный пункт определяется по признаку
SELECTED.
В многоуровневых меню ссылки на подразделы ведите на папку, а не на index.php
внутри неё - иначе подсветка активного пункта будет работать некорректно.
4. Хлебные крошки
<? $APPLICATION->AddChainItem("Форум «Отзывы»", "/ru/forum/list.php?FID=3"); ?>Пункт добавляется в конец цепочки. Вызывать можно из кода страницы или шаблона.
Сам компонент bitrix:breadcrumb ставят в шаблон сайта - тогда цепочка
появляется на всех страницах разом.
Справочник API
| Элемент | Назначение | Особенности |
|---|---|---|
.<тип>.menu.php | статическое меню раздела | массив $aMenuLinks |
.<тип>.menu_ext.php | динамическое меню | нужен array_merge и включённая опция подключения в компоненте |
пункт $aMenuLinks | пять элементов | название, ссылка, доп. ссылки, доп. параметры, условие показа |
bitrix:menu | вывод меню | параметры включают тип меню, уровни вложенности, кеш |
USE_EXT | подключение динамических файлов | без него menu_ext.php игнорируется |
$arItem['SELECTED'] | признак активного пункта | |
$arItem['ITEM_TYPE'] | тип пункта | раздел, страница, страница с параметрами |
$arItem['PERMISSION'] | уровень доступа | только для меню сайта |
bitrix:menu.sections | пункты из разделов инфоблока | вызывается внутри menu_ext.php |
bitrix:breadcrumb | навигационная цепочка | ставится в шаблон сайта |
AddChainItem() | добавление пункта в цепочку | добавляет в конец |
Частые ошибки
Меню исчезло в подразделе. Симптом: в одной ветке сайта меню пустое. Причина - файл меню в этом разделе, пусть даже пустой: поиск останавливается на нём и родительское меню не подхватывается. Файл нужно удалить или переименовать.
Динамическое меню не работает. Либо нет файла menu_ext.php, либо в
параметрах компонента bitrix:menu не включено подключение таких файлов.
Меню не заменилось при наследовании. Статическое меню заменяется только статическим, динамическое - только динамическим. Если ожидали, что динамика перекроет статику, - не перекроет.
Создали страницу с опцией «Добавить пункт меню» и потеряли меню раздела. Опция незаметно создаёт собственный файл меню в подразделе, а он скрывает унаследованное меню родителя во всей ветке.
Изменения не видны. Меню кешируется - очистите кеш. Если конкретный пункт не появляется, проверьте условие показа и права доступа.
Кеш меню разросся до неприличных размеров. Он зависит от адреса страницы,
поэтому на сайтах с большим числом страниц растёт быстро. Отключать его не
нужно - вынесите тяжёлые запросы из шаблона в menu_ext.php и настройте
зависимости кеша.
Частые вопросы
Почему меню в подразделе стало пустым?
Потому что поиск файла меню идёт вверх по разделам и останавливается на первом найденном - независимо от содержимого. Если в подразделе лежит пустой файл нужного типа, он и станет меню этой ветки, а родительское не подхватится. Решение простое: удалить или переименовать файл в подразделе.
Как построить меню из разделов каталога?
Через файл .тип.menu_ext.php: в нём вызывают компонент bitrix:menu.sections, получают массив пунктов и объединяют его со статическими через array_merge. Не забудьте включить в параметрах компонента bitrix:menu опцию подключения файлов menu_ext - это самая частая причина, по которой динамическое меню «не работает».
Где выводить хлебные крошки?
В шаблоне сайта, обычно сразу после шапки - тогда цепочка появится на всех страницах без правки каждой. Текст пунктов система берёт из заголовков разделов и названий элементов инфоблока, а произвольный пункт добавляется из кода методом AddChainItem().
Можно ли полностью изменить вёрстку меню?
Да. Скопируйте шаблон компонента в шаблон сайта и правьте копию: в цикле по результату доступны текст, ссылка, признак активности и тип пункта, а разметку списка можно заменить на любую свою. Правило то же, что и для остальных компонентов: файлы в папке /bitrix/ не трогаем.
Связанные темы
- Шаблоны сайта - куда встраивается меню
- Компоненты 2.0 - как кастомизировать шаблон компонента
- Инфоблоки - источник данных для динамического меню
- Многоуровневое меню: свои пункты и вывод из инфоблока - файлы меню и пункты из данных
- Хлебные крошки: правка цепочки и свои элементы - цепочка навигации на практике
- Раздел Компоненты и шаблоны