1С Битрикс · 6 мин чтения

Хлебные крошки в Битрикс: AddChainItem и настройка навигации

Хлебные крошки в Битрикс через AddChainItem - метод объекта $APPLICATION, который добавляет пункты в цепочку навигации: на кастомных PHP-страницах и в шаблонах компонентов инфоблоков. На практике с этим методом сталкиваюсь на каждом втором проекте на 1С-Битрикс - то крошки не появляются на нестандартной странице, потому что вызов забыли поставить до вывода шапки, то порядок пунктов не совпадает с реальной структурой каталога. Разберу, как метод работает изнутри, как выводить крошки вручную и как настроить автоматическую генерацию цепочки для каталога и инфоблоков.

Как Битрикс собирает цепочку навигации

За хранение цепочки отвечает объект $APPLICATION - в нём накапливается массив пунктов, каждый со своим названием и ссылкой. Вывод на странице делает компонент bitrix:breadcrumb, который в момент отрисовки шапки читает этот массив и превращает его в HTML.

Наполнить цепочку можно двумя способами, и на боевых проектах они обычно сочетаются:

  • автоматически - по структуре директорий сайта и файлам .section.php, без единого вызова AddChainItem;
  • вручную - явными вызовами AddChainItem в коде страницы или в компоненте.

Первый вариант удобен для статических информационных разделов вроде «О компании» или документации, второй - почти обязателен там, где страницы генерируются динамически: карточки товаров, разделы каталога, персональные страницы пользователя.

Синтаксис AddChainItem: параметры и порядок вызова

Метод принимает два аргумента:

$APPLICATION->AddChainItem($name, $link = false);

$name - текст пункта, обязателен. $link - необязательный URL: если пункт не последний в цепочке, ссылку лучше указывать всегда, иначе крошка выведется как неактивный текст и пользователь не сможет по ней перейти назад. Для последнего пункта (текущей страницы) ссылку обычно не передают - сам Битрикс не выводит её кликабельной, даже если адрес указан, но привычка не указывать её для текущей страницы избавляет от путаницы в коде.

Порядок вызовов метода - это порядок пунктов в итоговой цепочке, слева направо. Значит, для страницы товара сначала добавляется «Каталог», потом раздел, потом название товара:

$APPLICATION->SetTitle("Ноутбук Lenovo IdeaPad 3");
$APPLICATION->AddChainItem("Каталог", "/catalog/");
$APPLICATION->AddChainItem("Ноутбуки", "/catalog/noutbuki/");
$APPLICATION->AddChainItem("Lenovo IdeaPad 3");

Важный нюанс: все вызовы должны выполниться до подключения header.php, потому что именно в шапке обычно стоит компонент bitrix:breadcrumb, который читает уже накопленный на этот момент массив. Если вызвать AddChainItem после include шапки, крошка добавится в цепочку, но на странице уже не отрисуется - компонент к этому моменту отработал.

Заодно замечу: SetTitle и AddChainItem - разные вещи, хотя их часто путают. SetTitle задаёт тег <title> и заголовок H1 через системный шаблон, а AddChainItem - отдельный пункт в цепочке. Тексты специально делаю разными: для title беру более развёрнутую формулировку под запрос, а для крошки - короткое название, иначе цепочка на широких экранах не помещается в одну строку.

Ручной вывод крошек на нестандартных страницах

На страницах, не завязанных на инфоблок - лендингах, custom-модулях, страницах с самописной логикой - крошки нужно наполнять вручную в самом начале файла, ещё до подключения шапки:

<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");

$APPLICATION->SetTitle("Расчёт стоимости доставки");
$APPLICATION->AddChainItem("Доставка и оплата", "/delivery/");
$APPLICATION->AddChainItem("Калькулятор стоимости");

require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");
?>
<!-- контент страницы -->
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>

Эта схема закрывает большинство задач на статичных страницах. Проблема начинается там, где страница собирается из нескольких компонентов и не очевидно, какой из них должен добавить свой кусок цепочки - обычно в такой ситуации проще вынести формирование крошек в отдельный include-файл и подключать его первым, до всех остальных компонентов страницы.

Бесплатный материал

🎁 Полезный скрипт в подарок

Подпишитесь на Telegram - пришлю готовый скрипт по этой теме.

Без спама. Отписка в 1 клик.

Автоматическая цепочка через .section.php и bitrix:breadcrumb

Для статических разделов сайта Битрикс умеет строить цепочку без единого вызова AddChainItem - по файловой структуре. В каждой директории лежит служебный файл .section.php, а в нём - вызов SetTitle с названием раздела:

<?
$APPLICATION->SetTitle("Доставка и оплата");
?>

Когда компонент bitrix:breadcrumb работает в режиме построения по файловой системе, он сам поднимается по дереву каталогов от текущей страницы до корня и берёт название каждого уровня из его .section.php. Ручные вызовы AddChainItem в этом случае не нужны вообще - что удобно для сайтов-визиток и информационных разделов, где структура директорий совпадает со структурой меню.

Для каталога с инфоблоками этот механизм не подходит, потому что разделы и товары физически не лежат в отдельных папках - здесь работает второй, компонентный способ, о котором ниже.

Настройка компонента bitrix:breadcrumb под свой дизайн

Стандартный вызов компонента в header.php выглядит так:

$APPLICATION->IncludeComponent(
    "bitrix:breadcrumb",
    ".default",
    Array(
        "START_FROM" => "0",
        "PATH" => ""
    )
);

Параметр Назначение Пример
START_FROM С какого индекса цепочки начинать вывод (0 - с «Главная») 1 - убирает первый пункт
PATH Путь, для которого строить цепочку, если не текущий адрес /catalog/noutbuki/

Под свой дизайн шаблон компонента копирую в локальный шаблон сайта (/local/templates/ваш_шаблон/components/bitrix/breadcrumb/.default/) и правлю разметку в template.php - обычно там же лежит и микроразметка schema.org BreadcrumbList, за счёт которой крошки попадают в сниппет выдачи Google и Яндекса. Если верстальщик до меня переписывал шаблон с нуля, эту микроразметку часто просто забывают - стоит свериться, что itemscope itemtype="https://schema.org/BreadcrumbList" и вложенные itemprop остались на месте.

Хлебные крошки для инфоблоков: автоматическая цепочка по разделам

В компонентах каталога (catalog.section, catalog.element и их аналогах) есть параметр ADD_SECTIONS_CHAIN, который при значении «Да» сам добавляет в цепочку все родительские разделы товара или раздела - без единого явного AddChainItem в коде страницы. Это рабочий вариант в 90% случаев, но если шаблон компонента переписан вручную или используется собственный компонент без этого параметра, цепочку приходится собирать самому - обычно в component_epilog.php:

global $APPLICATION;
if (!empty($arResult['SECTION']['PATH'])) {
    foreach ($arResult['SECTION']['PATH'] as $arPath) {
        $APPLICATION->AddChainItem($arPath['NAME'], $arPath['SECTION_PAGE_URL']);
    }
}
$APPLICATION->AddChainItem($arResult['NAME']);

component_epilog.php здесь выбран не случайно: этот файл выполняется при каждом обращении к странице, даже когда сам компонент отдаётся из кэша - в отличие от кода внутри template.php, который при кэшировании компонента не выполнится повторно. Похожие заготовки для типовых доработок каталога и инфоблоков я собираю в библиотеке готовых скриптов - обычно быстрее взять рабочий кусок и адаптировать под конкретную структуру разделов, чем писать с нуля.

Типичные ошибки при работе с AddChainItem

  • Вызов после подключения шапки. Компонент bitrix:breadcrumb уже отрисовался, добавленный позже пункт в вывод не попадёт - крошка просто не появится, хотя в коде всё выглядит правильно.
  • Двойное наполнение цепочки. Когда одновременно включён ADD_SECTIONS_CHAIN у компонента каталога и добавлен ручной AddChainItem с тем же названием раздела в component_epilog.php - раздел в крошках дублируется. Нужно выбрать один источник.
  • Кэш компонента съедает вызов. Если AddChainItem стоит внутри закэшированного template.php, при отдаче страницы из кэша метод не выполнится и крошка пропадёт после первого захода на страницу. Решение - переносить вызов в component_epilog.php или отключать кэш для конкретного компонента.
  • Ссылка на несуществующую страницу. Для непоследнего пункта указан адрес, которого на сайте уже нет (переименовали раздел, а строку в коде не поправили) - крошка кликабельна, но ведёт на 404.

Если ошибка не находится с первого взгляда, начинаю с проверки: выполняется ли вообще нужный кусок кода на этом хите (не съеден ли кэшем компонента или страницы целиком), и только потом смотрю логику самого AddChainItem.

Чтобы сайт работал без сбоев

Техподдержка

от 15 000 ₽/мес

Подробнее →

Частые вопросы

Чем AddChainItem отличается от SetTitle?

SetTitle задаёт тег title страницы и заголовок H1 через системный шаблон, а AddChainItem - отдельный пункт в цепочке навигации. Тексты для них специально делаю разными: title развёрнутый под поисковый запрос, а название крошки короче, чтобы цепочка не растягивалась в две строки на мобильных.

Как убрать пункт «Главная» из цепочки хлебных крошек?

За это отвечает параметр START_FROM у компонента bitrix:breadcrumb. Индексация пунктов начинается с нуля, и «Главная» обычно стоит на позиции 0, поэтому START_FROM со значением 1 уберёт её из вывода, оставив остальную цепочку без изменений.

Почему крошки не обновляются после правки кода?

Чаще всего дело в управляемом кэше - компонент кэширует уже отрисованный HTML вместе с блоком крошек. Проверяю, включён ли кэш у конкретного компонента, чищу его через административную панель или переношу вызов AddChainItem в component_epilog.php, который выполняется вне зависимости от кэша шаблона.

Можно ли вывести крошки не в шапке, а в другом месте макета?

Да, компонент bitrix:breadcrumb можно вызвать в любом месте шаблона после того, как цепочка наполнена. Для полностью нестандартной вёрстки без стандартного компонента использую метод $APPLICATION->GetNavChain() - он возвращает массив пунктов цепочки, который дальше рендерю собственной разметкой.

Есть задача?

Обсудим в мессенджере

Расскажите, что нужно сделать — отвечу в течение 4 часов в рабочее время. Первая консультация бесплатно.

Самозанятый Калинкин Н. А. · работаю с физлицами и юрлицами

Продолжая пользование настоящим сайтом Вы выражаете своё согласие на обработку Ваших персональных данных (файлов куки) с использованием Yandex.Metrika.
Понятно