1С-Битрикс. Кастомные канонические урлы + rel="prev" и rel="next"
Поисковики их так сильно любят, что SEO-специалисты слёзно просят их внедрить на сайт.
Что ж, поехали.
В header.php вашего шаблона сайта, в секцию head, добавляем вызов отложенных функций для вывода ссылок вперёд/назад:
$APPLICATION->AddBufferContent([$APPLICATION, 'GetLink'], 'prev'); $APPLICATION->AddBufferContent([$APPLICATION, 'GetLink'], 'next');
В result_modifier.php вашего шаблона компонента (например, catalog.section) вставляем:
$arResult['NAV_RESULT_NAV_NUM'] = $arResult['NAV_RESULT']->NavNum; $arResult['NAV_RESULT_NAV_PAGE_NOMER'] = $arResult['NAV_RESULT']->NavPageNomer; $arResult['NAV_RESULT_NAV_PAGE_COUNT'] = $arResult['NAV_RESULT']->NavPageCount; $arResult['SECTION_SECTION_PAGE_URL'] = !empty($arResult['SECTION_PAGE_URL']) ? $arResult['SECTION_PAGE_URL'] : null; $this->__component->SetResultCacheKeys([ 'NAV_RESULT_NAV_NUM', 'NAV_RESULT_NAV_PAGE_NOMER', 'NAV_RESULT_NAV_PAGE_COUNT', 'SECTION_SECTION_PAGE_URL', ]);
Тут мы работаем с ключом NAV_RESULT массива $arResult. Он ничто иное как объект класса CDBResult. В его свойствах есть всё необходимое для нашей задачи.
Идём дальше.
В component_epilog.php вашего шаблона компонента (например, catalog.section) вставляем:
if ( isset($arResult['NAV_RESULT_NAV_NUM'], $arResult['NAV_RESULT_NAV_PAGE_NOMER'], $arResult['SECTION_SECTION_PAGE_URL']) && ( array_key_exists('PAGEN_' . $arResult['NAV_RESULT_NAV_NUM'], $_GET) || $arResult['NAV_RESULT_NAV_PAGE_NOMER'] > 1 ) ) { $APPLICATION->SetPageProperty('canonical', 'http://' . SITE_SERVER_NAME . $arResult['SECTION_SECTION_PAGE_URL']); } if ( isset( $arResult['NAV_RESULT_NAV_NUM'], $arResult['NAV_RESULT_NAV_PAGE_NOMER'], $arResult['NAV_RESULT_NAV_PAGE_COUNT'], $arResult['SECTION_SECTION_PAGE_URL'] ) ) { $paramName = sprintf('PAGEN_%s', $arResult['NAV_RESULT_NAV_NUM']); if ($arResult['NAV_RESULT_NAV_PAGE_COUNT'] > $arResult['NAV_RESULT_NAV_PAGE_NOMER']) { // next $urlNextRel = htmlspecialcharsbx( CHTTP::urlAddParams( CHTTP::urlDeleteParams( $arResult['SECTION_SECTION_PAGE_URL'], $paramName, [ 'delete_system_params' => true ] ), [ $paramName => $arResult['NAV_RESULT_NAV_PAGE_NOMER'] + 1, ], [ 'skip_empty' => true, ] ) ); } if ($arResult['NAV_RESULT_NAV_PAGE_NOMER'] > 1) { // prev $urlPrevRel = htmlspecialcharsbx( CHTTP::urlAddParams( CHTTP::urlDeleteParams( $arResult['SECTION_SECTION_PAGE_URL'], $paramName, [ 'delete_system_params' => true ] ), [ $paramName => ( ($arResult['NAV_RESULT_NAV_PAGE_NOMER'] - 1) == 1 ? '' : $arResult['NAV_RESULT_NAV_PAGE_NOMER'] - 1 ), ], [ 'skip_empty' => true, ] ) ); } if (isset($urlNextRel)) { $APPLICATION->SetPageProperty('next', 'http://' . SITE_SERVER_NAME . $urlNextRel); } if (isset($urlPrevRel)) { $APPLICATION->SetPageProperty('prev', 'http://' . SITE_SERVER_NAME . $urlPrevRel); } }
Тут и происходит основная логика. Формируем rel="canonical". Фомируем rel="prev" и rel="next".
Как вы понимаете, добавить поддержку этих тегов можно в любой компонент, имеющий $arResult['NAV_RESULT']
P.S. а если и нет в компоненте $arResult['NAV_RESULT'] (например тот же bitrix:blog.blog), то это можно исправить одной строкой в коде компонента так:
После строчки:
$arResult["NAV_STRING"] = $dbPost->GetPageNavString(GetMessage("MESSAGE_COUNT"), $arParams["NAV_TEMPLATE"], false, $component);
нужно добавить:
$arResult["NAV_RESULT"] = $dbPost;
А чтобы не забылось, что вы в ядре поправили, ставьте модуль
8 комментариев
Не совсем понял, а функция GetLink где?
Иван, GetLink — это метод класса \CMain.
Олег, спасибо за ответ, но что-то я не вижу в документации метод GetLink у класса CMain
В документации есть не всё. Смотрите исходный код. Ну или тут https://bxapi.ru/src/?module_id=main&name=CMain%3A%3AGetLink
Спасибо! Работает! :-)
В свежем (натекущий момент) Битриксе уже появился метод ShowLink() , поэтому в шаблоне сайта можно писать так: $APPLICATION->ShowLink('prev', 'prev'); $APPLICATION->ShowLink('next', 'next');
С каноникалом у вас неаккуратно, надо как-то так: ($APPLICATION->IsHTTPS() ? 'https://' : 'http://')
Ничего не работает, все функции не документированы. При использование этого кода выводится http://site.ru?PAGEN_1=2#SITE_DIR#/catalog/#SECTION_CODE#/
Все работает отлично, никаких косяков типа "http://site.ru?" - нет! Правда к коду автора учитывались комменты, в частности: #602 Михаил 21 ноября 2017 в 20:27 Спасибо за решение!