Сегодня мы займемся реализацией очень полезного функционала, который точно есть в 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
Я не большой специалист по js и строчка if (!document.getElementById) return; меня немного удивила. Причем ту статью я читал раньше, но как-то обратил внимание на это только сейчас. И часто эта функция может отсутствовать, Алексей?
Смотрю стандартную демку.
Пишу в настройках компонента новостей в поле «Название шаблона:» — arrows
И получаю такую навигацию.
Шаблон живет тут:
/bitrix/components/bitrix/system.pagenavigation/templates/arrows/
а.. прочитал ещё раз..
совсем про другое речь идет..
пошел дальше :)
Serge, стандартно навигация выводится или в списке элементов для постраничной навигации или внутри конкретного элемента, когда он разбит на несколько страниц. Чтобы из элемента перейти на следующий (предыдущий) элемент — такого в дефолтных шаблонах нет.
не подскажешь как сделать рейтинг для каждого товара виде звезд?
Делаю все как написано — ничего не происходит ((
Спасибо, ваша статья очень помогла.
в arParams не попадает $arParams[«SORT_ORDER1»] можешь помочь??
Спасибо! Спер, все работает!
Спасибо, пригодилось!
А как ограничеть эту нагигацыю пределами разделов инфоблока, чтобы пользователь не перепрыгивал с тостера на телевизор, если они добавлены рядом?
В коде выше есть закомментированная строка
//"SECTION_CODE" => $arParams[«SECTION_CODE»]
Она отвечает за ограничение секцией. Можно вместо CODE поставить ID, смотря как реализована адресация.
Спсибо! Действительно, нужно было просто вместо code вписать id
Что то похоже что это только в catalog.element работат, а в news.detail нет..
нет работат, только для ограничения по разделам нужно заменять вызов «SECTION_CODE» => $arParams[«SECTION_CODE»],
на
«IBLOCK_SECTION_ID» => $arParams[«IBLOCK_SECTION_ID»],
если используется построение адреса с использованием ID раздела
хотя раздел это всё равно не ограничивает как в catalog.element ((
Не могу понять как реализорвать Превью картинки сл и пред. новости подскажите?
В result modifer и в шаблоне
Все хорошо работает)
Но почему то весь catalog.element оказывается под подвалом на странице…
После нескольких бесцельных листаний туда обратно по элементам все становится на место.
С чем это может быть связано???
Мария, перемещение блоков на странице в 99% случаев связано с неправильной таблицей стилей css. Возможно дело в кэше.
Спасибо большое, то, что нужно!
Огромное спасибо, очень полезный код, полезная статья!
А как сделать ссылки на соседние секции? У меня, допустим, Секция «Одежда», «Обувь», «Аксессуары». Хочу, что в Одежде были ссылки генерируемые на Обувь и Аксессуарах. Все 3 находятся внутри одного раздела
На сайте в компоненте catalog.element уже есть свой файл result_modifier.php
Встраиваю в него всё из вашего примера, чего там не хватало. В шаблоне тоже добавляю в нужном месте блок вывода ссылок. И натурально ничего не происходит. Как быть, где искать? Подскажите пожалуйста.
Здравствуйте!
Подскажите пожалуйста, как можно сделать так, чтобы при детальном просмотре новости можно было переходить к следующей и предыдущей не по ID новости, а по числу сортировки (которое 500 по умолчанию)? Что нужно поменять в вашем коде?
Владимир, смотрите строчки 23 и 8 result_modifier.php
Вася:
04.06.2014 в 17:14
А как сделать ссылки на соседние секции?
Мне тоже очень нужно!! Подскажите!
Спасибо! Огромное!
реальное спасибо! и почему такую простую но нужную фичу не могут сделать в самом битриксе…
Спасибо огромное!!!