Сегодня мы займемся реализацией очень полезного функционала, который точно есть в WordPress, скорее всего присутствует в других движках, но почему-то не сделан по умолчанию в 1с-Битрикс. А именно, в шаблоне вывода детальной новости (товара в каталоге или вообще любого элемента инфоблока) отобразим ссылки на предыдущий и последующий элементы. Это даст возможность пользователю не возвращаться в список и просматривать материалы сайта «по цепочке».

Технически получить «соседей» фиксированного элемента инфоблока без лишних запросов к базе данных стало возможно после ввода в функцию CIBlockElement::GetList нового параметра «nElementID». Он задает количество соседних элементов с каждой стороны, которые следует включить в выборку.

Итак, первым делом копируем шаблон компонента news.detail (catalog.element или они могут входить в состав комплексного news, catalog) и создаем в директории с template.php файл result_modifier.php

<?
// сортировку берем из параметров компонента
$arSort = array(
        $arParams["SORT_BY1"]=>$arParams["SORT_ORDER1"],
        $arParams["SORT_BY2"]=>$arParams["SORT_ORDER2"],
    );
// выбрать нужно id элемента, его имя и ссылку. Можно добавить любые другие поля, например PREVIEW_PICTURE или PREVIEW_TEXT
$arSelect = array(
        "ID",
        "NAME",
        "DETAIL_PAGE_URL"
    );
// выбираем активные элементы из нужного инфоблока. Раскомментировав строку можно ограничить секцией
$arFilter = array (
        "IBLOCK_ID" => $arResult["IBLOCK_ID"],
        //"SECTION_CODE" => $arParams["SECTION_CODE"],
        "ACTIVE" => "Y",
        "CHECK_PERMISSIONS" => "Y",
    );
// выбирать будем по 1 соседу с каждой стороны от текущего
$arNavParams = array(
        "nPageSize" => 1,
        "nElementID" => $arResult["ID"],
    );
$arItems = Array();
$rsElement = CIBlockElement::GetList($arSort, $arFilter, false, $arNavParams, $arSelect);
$rsElement->SetUrlTemplates($arParams["DETAIL_URL"]);
while($obElement = $rsElement->GetNextElement())
        $arItems[] = $obElement->GetFields();
// возвращается от 1го до 3х элементов в зависимости от наличия соседей, обрабатываем эту ситуацию		
if(count($arItems)==3):
    $arResult["TORIGHT"] = Array("NAME"=>$arItems[0]["NAME"], "URL"=>$arItems[0]["DETAIL_PAGE_URL"]);
    $arResult["TOLEFT"] = Array("NAME"=>$arItems[2]["NAME"], "URL"=>$arItems[2]["DETAIL_PAGE_URL"]);
elseif(count($arItems)==2):
    if($arItems[0]["ID"]!=$arResult["ID"])
        $arResult["TORIGHT"] = Array("NAME"=>$arItems[0]["NAME"], "URL"=>$arItems[0]["DETAIL_PAGE_URL"]);
    else
        $arResult["TOLEFT"] = Array("NAME"=>$arItems[1]["NAME"], "URL"=>$arItems[1]["DETAIL_PAGE_URL"]);
endif;
// в $arResult["TORIGHT"] и $arResult["TOLEFT"] лежат массивы с информацией о соседних элементах
?>

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

<?if(is_array($arResult["TOLEFT"])):?><a class="fleft" id="previous_page" href="<?=$arResult["TOLEFT"]["URL"]?>">< <?=$arResult["TOLEFT"]["NAME"]?></a><?endif?>
<?if(is_array($arResult["TORIGHT"])):?><a class="fright" id="next_page" href="<?=$arResult["TORIGHT"]["URL"]?>"><?=$arResult["TORIGHT"]["NAME"]?> ></a><?endif?>

Для удобства пользователей можно обрабатывать нажатия клавиш ctrl+стрелка влево и ctrl+стрелка вправо. Создадим или откроем для редактирования в директории редактируемого шаблона файл script.js (функция взята из этой статьи)

document.onkeydown = PageNavigation;

function PageNavigation (event)
{
   if (!document.getElementById)
      return;

   if (window.event) 
      event = window.event;

   if (event.ctrlKey)
   {
      var key = (event.keyCode ? event.keyCode : (event.which ? event.which : null) );
      if (!key)
         return;

      var link = null;
      if (key == 39)
         link = document.getElementById('next_page');
      else if (key == 37)
         link = document.getElementById('previous_page');

      if (link && link.href)
         document.location = link.href;
   }
}

Сжатый вариант кода:

document.onkeydown=PageNavigation;function PageNavigation(a){if(!document.getElementById)return;if(window.event)a=window.event;if(a.ctrlKey){var b=(a.keyCode?a.keyCode:(a.which?a.which:null));if(!b)return;var c=null;if(b==39)c=document.getElementById('next_page');else if(b==37)c=document.getElementById('previous_page');if(c&&c.href)document.location=c.href}}

Таким образом легко и просто можно получить очень удобную, современную навигацию по динамическому контенту.

Больше статей и материалов по web-разработке в tg-канале - подписывайтесь!

Подписаться в telegram

29 комментариев “Ссылки на соседние элементы инфоблока

  1. Kola

    Я не большой специалист по js и строчка if (!document.getElementById) return; меня немного удивила. Причем ту статью я читал раньше, но как-то обратил внимание на это только сейчас. И часто эта функция может отсутствовать, Алексей?

  2. Serge

    Смотрю стандартную демку.
    Пишу в настройках компонента новостей в поле «Название шаблона:» — arrows
    И получаю такую навигацию.
    Шаблон живет тут:
    /bitrix/components/bitrix/system.pagenavigation/templates/arrows/

  3. Serge

    а.. прочитал ещё раз..
    совсем про другое речь идет..
    пошел дальше :)

  4. Алексей Валеев

    Serge, стандартно навигация выводится или в списке элементов для постраничной навигации или внутри конкретного элемента, когда он разбит на несколько страниц. Чтобы из элемента перейти на следующий (предыдущий) элемент — такого в дефолтных шаблонах нет.

  5. Almat

    не подскажешь как сделать рейтинг для каждого товара виде звезд?

  6. Виктория

    Спасибо, ваша статья очень помогла.

  7. андрей

    в arParams не попадает $arParams[«SORT_ORDER1»] можешь помочь??

  8. Alexander Kozlov

    Спасибо! Спер, все работает!

  9. Ярослав

    Спасибо, пригодилось!

  10. sap

    А как ограничеть эту нагигацыю пределами разделов инфоблока, чтобы пользователь не перепрыгивал с тостера на телевизор, если они добавлены рядом?

  11. Алексей Валеев

    В коде выше есть закомментированная строка
    //"SECTION_CODE" => $arParams[«SECTION_CODE»]
    Она отвечает за ограничение секцией. Можно вместо CODE поставить ID, смотря как реализована адресация.

  12. sap

    Спсибо! Действительно, нужно было просто вместо code вписать id

  13. sap

    Что то похоже что это только в catalog.element работат, а в news.detail нет..

  14. sap

    нет работат, только для ограничения по разделам нужно заменять вызов «SECTION_CODE» => $arParams[«SECTION_CODE»],
    на
    «IBLOCK_SECTION_ID» => $arParams[«IBLOCK_SECTION_ID»],

    если используется построение адреса с использованием ID раздела

  15. sap

    хотя раздел это всё равно не ограничивает как в catalog.element ((

  16. Виталий

    Не могу понять как реализорвать Превью картинки сл и пред. новости подскажите?

    В result modifer и в шаблоне

  17. Мария

    Все хорошо работает)
    Но почему то весь catalog.element оказывается под подвалом на странице…
    После нескольких бесцельных листаний туда обратно по элементам все становится на место.
    С чем это может быть связано???

  18. Алексей Валеев

    Мария, перемещение блоков на странице в 99% случаев связано с неправильной таблицей стилей css. Возможно дело в кэше.

  19. Александр

    Спасибо большое, то, что нужно!

  20. Александр

    Огромное спасибо, очень полезный код, полезная статья!

  21. Вася

    А как сделать ссылки на соседние секции? У меня, допустим, Секция «Одежда», «Обувь», «Аксессуары». Хочу, что в Одежде были ссылки генерируемые на Обувь и Аксессуарах. Все 3 находятся внутри одного раздела

  22. Вова-Володя

    На сайте в компоненте catalog.element уже есть свой файл result_modifier.php
    Встраиваю в него всё из вашего примера, чего там не хватало. В шаблоне тоже добавляю в нужном месте блок вывода ссылок. И натурально ничего не происходит. Как быть, где искать? Подскажите пожалуйста.

  23. Владимир

    Здравствуйте!
    Подскажите пожалуйста, как можно сделать так, чтобы при детальном просмотре новости можно было переходить к следующей и предыдущей не по ID новости, а по числу сортировки (которое 500 по умолчанию)? Что нужно поменять в вашем коде?

  24. Таня

    Вася:
    04.06.2014 в 17:14

    А как сделать ссылки на соседние секции?

    Мне тоже очень нужно!! Подскажите!

  25. Ксения

    Спасибо! Огромное!

  26. влад

    реальное спасибо! и почему такую простую но нужную фичу не могут сделать в самом битриксе…

  27. Елена

    Спасибо огромное!!!

Добавить комментарий

Ваш адрес email не будет опубликован.