Назад

Битрикс как сделать ссылку на следующую и предыдущую новость

Главная
Блог
Битрикс как сделать ссылку на следующую и предыдущую новость

Навигация между элементами инфоблока — важный элемент UX, который позволяет пользователям легко перемещаться между связанными материалами. В этой статье я расскажу о нескольких способах реализации такой навигации в CMS 1С-Битрикс.

Способ 1: Базовая реализация через CIBlockElement::GetList

Самый простой способ добавить навигацию — модифицировать шаблон компонента news.detail:

<?
// В файле template.php вашего шаблона
$arFilter = array(
    "IBLOCK_ID" => $arResult["IBLOCK_ID"],
    "ACTIVE" => "Y",
    "CHECK_PERMISSIONS" => "Y"
);

$arSelect = array("ID", "NAME", "DETAIL_PAGE_URL");

// Получаем предыдущий элемент
$resPrev = CIBlockElement::GetList(
    array("SORT" => "ASC", "ID" => "DESC"),
    $arFilter,
    false,
    array("nElementID" => $arResult["ID"], "nPageSize" => 1),
    $arSelect
);
$arPrev = $resPrev->GetNext();

// Получаем следующий элемент
$resNext = CIBlockElement::GetList(
    array("SORT" => "DESC", "ID" => "ASC"),
    $arFilter,
    false,
    array("nElementID" => $arResult["ID"], "nPageSize" => 1),
    $arSelect
);
$arNext = $resNext->GetNext();
?>

<?if($arPrev || $arNext):?>
<div class="news-navigation">
    <?if($arPrev):?>
        <a href="<?=$arPrev["DETAIL_PAGE_URL"]?>" class="news-navigation-prev">
            ← <?=$arPrev["NAME"]?>
        </a>
    <?endif;?>
    
    <?if($arNext):?>
        <a href="<?=$arNext["DETAIL_PAGE_URL"]?>" class="news-navigation-next">
            <?=$arNext["NAME"]?> →
        </a>
    <?endif;?>
</div>
<?endif;?>

Способ 2: Улучшенная версия с учетом разделов

Для более точной навигации, особенно в сложных структурах, следует учитывать разделы:

<?
$arFilter = array(
    "IBLOCK_ID" => $arResult["IBLOCK_ID"],
    "ACTIVE" => "Y",
    "ACTIVE_DATE" => "Y"
);

// Учитываем текущий раздел
if ($arResult["IBLOCK_SECTION_ID"]) {
    $arFilter["SECTION_ID"] = $arResult["IBLOCK_SECTION_ID"];
    $arFilter["INCLUDE_SUBSECTIONS"] = "Y";
}

// Используем кэширование
$cache = new CPHPCache();
$cacheTime = 3600;
$cacheID = 'news_nav_'.$arResult["ID"];
$cachePath = '/news_navigation/';

if ($cache->InitCache($cacheTime, $cacheID, $cachePath)) {
    $arNav = $cache->GetVars();
} elseif ($cache->StartDataCache()) {
    $res = CIBlockElement::GetList(
        array(
            $arParams["SORT_BY1"] => $arParams["SORT_ORDER1"],
            $arParams["SORT_BY2"] => $arParams["SORT_ORDER2"],
            "ID" => "ASC"
        ),
        $arFilter,
        false,
        array("nElementID" => $arResult["ID"], "nPageSize" => 1),
        array("ID", "NAME", "DETAIL_PAGE_URL", "PREVIEW_PICTURE")
    );
    
    $arNav = array();
    while ($item = $res->GetNext()) {
        $arNav[] = $item;
    }
    
    $cache->EndDataCache($arNav);
}

// Определяем соседние элементы
if (count($arNav) > 2) {
    $arResult["PREV"] = $arNav[2]; // Предыдущий
    $arResult["NEXT"] = $arNav[0]; // Следующий
} elseif (count($arNav) == 2) {
    if ($arNav[0]["ID"] == $arResult["ID"]) {
        $arResult["PREV"] = $arNav[1];
    } else {
        $arResult["NEXT"] = $arNav[0];
    }
}
?>

<?if($arResult["PREV"] || $arResult["NEXT"]):?>
<div class="news-navigation">
    <?if($arResult["PREV"]):?>
        <a href="<?=$arResult["PREV"]["DETAIL_PAGE_URL"]?>" class="prev-link">
            <span class="arrow">←</span>
            <span class="title"><?=$arResult["PREV"]["NAME"]?></span>
            <?if($arResult["PREV"]["PREVIEW_PICTURE"]):?>
                <img src="<?=CFile::GetPath($arResult["PREV"]["PREVIEW_PICTURE"])?>" alt="" class="preview-img">
            <?endif;?>
        </a>
    <?endif;?>
    
    <?if($arResult["NEXT"]):?>
        <a href="<?=$arResult["NEXT"]["DETAIL_PAGE_URL"]?>" class="next-link">
            <span class="title"><?=$arResult["NEXT"]["NAME"]?></span>
            <span class="arrow">→</span>
            <?if($arResult["NEXT"]["PREVIEW_PICTURE"]):?>
                <img src="<?=CFile::GetPath($arResult["NEXT"]["PREVIEW_PICTURE"])?>" alt="" class="preview-img">
            <?endif;?>
        </a>
    <?endif;?>
</div>
<?endif;?>

Способ 3: Использование встроенных возможностей компонента

  1. В параметрах компонента установите:

"SHOW_NAVIGATION" => "Y",
"PREV_LINK_NAME" => "Предыдущая новость",
"NEXT_LINK_NAME" => "Следующая новость",

  1. Для кастомизации создайте в шаблоне компонента файл result_modifier.php:

<?
if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die();

// Улучшаем навигацию
if ($arParams["SHOW_NAVIGATION"] == "Y") {
    $arFilter = array(
        "IBLOCK_ID" => $arResult["IBLOCK_ID"],
        "ACTIVE" => "Y"
    );
    
    if ($arResult["IBLOCK_SECTION_ID"]) {
        $arFilter["SECTION_ID"] = $arResult["IBLOCK_SECTION_ID"];
    }
    
    $res = CIBlockElement::GetList(
        array("SORT" => "ASC", "ID" => "DESC"),
        $arFilter,
        false,
        array("nElementID" => $arResult["ID"], "nPageSize" => 1),
        array("ID", "NAME", "DETAIL_PAGE_URL")
    );
    
    $arNav = array();
    while ($item = $res->GetNext()) {
        $arNav[] = $item;
    }
    
    if (count($arNav) > 2) {
        $arResult["PREV"] = $arNav[2];
        $arResult["NEXT"] = $arNav[0];
    }
}
?>

Рекомендации по реализации

  1. Производительность:

    • Всегда используйте кэширование

    • Ограничивайте выборку только нужными полями

    • Для больших инфоблоков используйте фильтрацию по разделам

  2. UX улучшения:

    • Добавляйте превью изображений к навигации

    • Реализуйте микроразметку для SEO

    • Добавьте подсказки при наведении

  3. SEO аспекты:

    • Используйте rel="prev" и rel="next" в ссылках

    • Добавьте микроразметку Schema.org

    • Обеспечьте корректные 301 редиректы при изменении URL

Пример микроразметки:

<div class="news-navigation" itemscope itemtype="http://schema.org/ItemList">
    <?if($arPrev):?>
        <a href="<?=$arPrev["DETAIL_PAGE_URL"]?>" itemprop="previousItem">
            ← <span itemprop="name"><?=$arPrev["NAME"]?></span>
        </a>
    <?endif;?>
    
    <?if($arNext):?>
        <a href="<?=$arNext["DETAIL_PAGE_URL"]?>" itemprop="nextItem">
            <span itemprop="name"><?=$arNext["NAME"]?></span> →
        </a>
    <?endif;?>
</div>

Заключение

Реализация навигации между новостями в Битрикс может быть как простой, так и достаточно сложной — в зависимости от требований проекта. Представленные в статье методы покрывают большинство типовых scenarios, от базовых до продвинутых.

Для дополнительной информации рекомендую обратиться к официальной документации:

Нужен надежный исполнитель?
Разрабатываем сайты, выполняем миграцию на Битрикс, дорабатываем функционал, сопровождаем проекты, а также занимаемся поисковым продвижением и комплексным маркетингом
Получить консультацию
Читайте по теме
Все статьи
Нужен надежный исполнитель?
Разрабатываем сайты, выполняем миграцию на Битрикс, дорабатываем функционал, сопровождаем проекты, а также занимаемся поисковым продвижением и комплексным маркетингом
Получить консультацию
Все статьи