Как в 1С-Битрикс вывести имя раздела и ссылку на него
Зная ID раздела, в битриксе очень просто вывести его имя, а также узнать, по какой ссылке он доступен.
Ссылка формируется из настроек инфоблока. Чтобы все ваши ссылки отображались корректно, настройки внутри инфоблока и вашего компонента должны совпадать.
Для того чтобы вывести имя раздела будем использовать API Битрикса.
GetNext(); ?> ">
$arItem[‘IBLOCK_SECTION_ID’] – ID раздела, имя которого мы хотим вывести
$ar_res[‘SECTION_PAGE_URL’] – ссылка на раздел
$ar_res[‘NAME’] – имя раздела
автор: Dmitriy
З 2011 року займаюся веб-розробкою. Зараз я – PHP Full Stack Developer.
Обговорити ваш проект, а також дізнатися більше про мене ви можете на цьому сайті:
dev.forwww.com
Читайте також:
15 коментаря
Хочу сделать возможной вывод списка новостей принадлежащих только конкретному разделу. Как это сделать?
Dmitriy :
Вам нужно воспользоваться методом CIblockElement::GetList
https://dev.1c-bitrix.ru/api_help/iblock/classes/ciblockelement/getlist.php Я вкратце писал об этом, посмотрите https://forwww.com/bitrix-how-to-get-element-and-section-list/ Во втором массиве, он же arFilter, вам нужно указать как минимум 3 параметра Array(“IBLOCK_ID” => $iblock_id, “ACTIVE” => “Y”, “SECTION_ID” => $SECTION_ID), – где нужно указать id инфоблока и секции, а также указать что будем выбирать только активные элементы. ПС извиняюсь что ответил с задержкой, спам фильтр жёстко работает
Ну вот сижу зациклился на разделах инфоблока и упорно пишу туда код раздела инфоблока, а не самого инфоблока. Поставил свой, толку мало, вижу на странице только название страницы содержание раздела инфоблока теперь не выводится.
Dmitriy :
Попробуйте перед кодом добавить
Dmitriy :
в более новых версиях битрикса есть выбор основного раздела, по которому и строится урл, плюс в настройках компонента вам нужно обязательно включить показ 404 страницы, чтобы при введении разных символов сервер отдавал 404. В настройках инфоблока, если я не путаю, можно найти выбор основного раздела
12412421 :
не работает
Dmitriy :
попробуйте перед подключить модуль инфоблока
Николай :
Добрый день! Это не работает, если элемент относится сразу к двум разделам. Нашел решение:
Fetch()) $temp++; // Проверим, к какому количеству разделов принадлежит элемент
>
if ($temp == 1) < // Если элемент принадлежит только к одному разделу
$db_old_groups = CIBlockElement::GetElementGroups($arItem[‘ID’], false);
while($ar_group = $db_old_groups->Fetch()) echo ‘Раздел: ‘ . $ar_group[“NAME”];
>
>
else < // Если элемент принадлежит более чем к одному разделу
echo ‘Разделы: ‘;
$db_old_groups = CIBlockElement::GetElementGroups($arItem[‘ID’], false);
while($ar_group = $db_old_groups->Fetch()) echo $ar_group[“NAME”] . ‘ ‘;
>
>
?> … но не могу понять как сделать ссылками эти разделы.
Dmitriy :
Добрый день, Дмитрий.
Не могу понять в чем ошибка.
С помощью GetList вывожу список папок инфоблока:
“ASC”),
Array(“IBLOCK_ID” => 5, “ACTIVE” => “Y”),
false,
Array(‘ID’, ‘NAME’, ‘CODE’, ‘SECTION_PAGE_URL’)
);
while($ar_fields = $my_sections->GetNext())
?> При переходе на ссылку детального просмотра содержимого папки – отображается все содержимое инфоблока, плюс URL прописывается : ” http://www.site.ru/kalendar/march/ “, т.е. index.php не дописывает. В настройках комплексого компонента news включен режим ЧПУ:
Страница общего списка: #SECTION_CODE#/
Страница раздела: #SECTION_CODE#/
Страница детального просмотра: #SECTION_CODE#/#ELEMENT_CODE#/ В настройках инфоблока прописано:
URL страницы информационного блока: #SITE_DIR#/kalendar/
URL страницы раздела: #SITE_DIR#/kalendar/#SECTION_CODE#/
URL страницы детального просмотра: #SITE_DIR#/kalendar/#SECTION_CODE#/#ELEMENT_CODE#/ Подскажите пожалуйста в чем ошибка или какую информацию почитать?
Dmitriy :
ну не глядя 2 причины возможны:
1. возможно вам нужно внутри компонента включать настроку ЧПУ и там дополнительно прописать правила формирования (проверить что они добавились в файл urlrerwite.php)
2. возможно у ваших элементов не сгенерирован символьный код
Предыдущий код не корректно отобразился – продублировала.
“ASC”),
Array(“IBLOCK_ID” => 5, “ACTIVE” => “Y”),
false,
Array(‘ID’, ‘NAME’, ‘CODE’, ‘SECTION_PAGE_URL’)
); while($ar_fields = $my_sections->GetNext())
?>
morozVA / gist:27d51d9000a3ab75f4fc6425221f515f
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Сначала получаем id нашего раздела. Для этого воспользуемся очень удобным, но не документированным (ох уж этот Битрикс) классом CIBlockFindTools и его методом GetSectionID. В section.php перед выводом нашего заголовка пишем: |
| $arResult[«SECTION_ID»] = CIBlockFindTools::GetSectionID( |
| $arResult[«VARIABLES»][«SECTION_ID»], |
| $arResult[«VARIABLES»][«SECTION_CODE»], |
| array(«IBLOCK_ID» => $arParams[«IBLOCK_ID»]) |
| ); |
| $sResult = CIBlockSection::GetByID($arResult[«SECTION_ID»]); |
| if($sArResult = $sResult->GetNext()) |
| Можно вывести и не имя, а любое другое поле, например UF_TITLE =) |
| Значит для получения любого поля раздела инфоблока нам достаточно знать только SECTION_CODE нужного инфоблока. Данный код работает при включенном ЧПУ и уникальности символьного кода раздела. |
| $arResult[«ELEMENT_ID»] = CIBlockFindTools::GetElementID( |
| $arResult[«VARIABLES»][«ELEMENT_ID»], |
| $arResult[«VARIABLES»][«ELEMENT_CODE»], |
| false, |
| false, |
| array( |
| «IBLOCK_ID» => $arParams[«IBLOCK_ID»], |
| «IBLOCK_LID» => SITE_ID, |
| «IBLOCK_ACTIVE» => «Y», |
| «ACTIVE_DATE» => «Y», |
| «ACTIVE» => «Y», |
| «CHECK_PERMISSIONS» => «Y», |
| ) |
| ); |
| А так можно получить количество подразделов в разделе |
| $arFilter = Array( |
| «IBLOCK_ID»=>$arParams[‘IBLOCK_ID’], |
| «SECTION_ID»=>$arResult[«SECTION_ID»] |
| ); |
| echo CIBlockSection::GetCount($arFilter); |
Один из вариантов работы с ЧПУ
Способы включения подразделов инфоблоков в пути для ЧПУ не раз обсуждались и эти способы были разными. В этой статье я хочу описать ещё один способ.
Суть моего решения состоит в том, чтобы до подключения компонента заменять $_SERVER[«REQUEST_URI»] на понятный для компонента путь, а затем в result_modifier.php возвращать в $_SERVER[«REQUEST_URI»] путь понятный для пользователя, т.е. со всеми подразделами.
Опишу по пунктам, что необходимо сделать, чтобы на сайте заработали правила ЧПУ вида:
#НАЗВАНИЕ_РАЗДЕЛА#/ #НАЗВАНИЕ_ПОДРАЗДЕЛОВ#/ #НАЗВАНИЕ_ЭЛЕМЕНТА#/
UPD. В последней версии продукта вышла возможность реализовать подобный функционал стандартно, используя в шаблонах ссылок #SECTION_CODE_PATH #
Настройки.
1. В настройках инфоблока указываем:
| URL страницы информационного блока: #SITE_DIR#test/ URL страницы раздела: #SITE_DIR#test/#SECTION_CODE#/ URL страницы детального просмотра: #SITE_DIR#test/#ELEMENT_CODE#/ |
2. В настройках компонента «Каталог» указываем:
| Включить поддержку ЧПУ: Да Каталог ЧПУ (относительно корня сайта): /test/ Раздел: #SECTION_ID#/ Детальная информация: #SECTION_ID#/#ELEMENT_ID#/ |
Конечно же «test» в обоих случаях необходимо заменить на путь к Вашему разделу.
Код.
1. В файл «/bitrix/php_interface/init.php» вставляем:
GetCurDir(false) ); $uri = $GLOBALS["BACK_REQUEST_URI"] = $APPLICATION->GetCurDir(false); $uri = str_replace($sef_folder, "", $uri); $uri = trim($uri, "/"); $tmp_uri = ""; if($uri && CModule::IncludeModule("iblock")) < $rs = CIBlockElement::GetList( array(), array("=CODE" =>$uri), false, array("nTopCount" => 1), array("ID", "IBLOCK_ID", "IBLOCK_SECTION_ID", "NAME") ); if($ar = $rs->Fetch()) < $tmp_uri = $sef_folder.intval($ar["IBLOCK_SECTION_ID"])."/".$ar["ID"]."/"; >else < $rs = CIBlockSection::GetList( array(), array("=CODE" =>$uri), false, array("ID") ); if($ar = $rs->Fetch()) < $tmp_uri = $sef_folder.$ar["ID"]."/"; >> > if($tmp_uri) < $_SERVER["REQUEST_URI"] = $REQUEST_URI = $tmp_uri; $APPLICATION->sDocPath2 = $tmp_uri."index.php"; CSubsections::InitParser(); > elseif($sef_folder == $APPLICATION->GetCurDir(false)) < CSubsections::InitParser(); >> function Back($arResult) < global $APPLICATION; $arResult["URL_TEMPLATES"]["section"] = "#SECTION_CODE#/"; $arResult["URL_TEMPLATES"]["element"] = "#ELEMENT_CODE#/"; $_SERVER["REQUEST_URI"] = $REQUEST_URI = $GLOBALS["BACK_REQUEST_URI"]; $APPLICATION->sDocPath2 = $GLOBALS["BACK_REQUEST_URI"]."index.php"; unset($GLOBALS["BACK_REQUEST_URI"]); > function Parse($html) < $html = str_ireplace("%"."2f", "/", $html); >function InitParser() < if(!defined("CSUBSECTIONS_INIT_HANDLER")) < define("CSUBSECTIONS_INIT_HANDLER", true); AddEventHandler("main", "OnEndBufferContent", array("CSubsections", "Parse"), 10000); >> function GetCode($iblock_id, $section_id, $element_name="") < $arPath = array(); if(CModule::IncludeModule("iblock")) < if($element_name) < $element_name = CUtil::translit($element_name, LANGUAGE_ID); $element_name = $element_name? "/".$element_name: ""; >if($rs = CIBlockSection::GetNavChain($iblock_id, $section_id)) < while($ar = $rs->Fetch()) < $arPath[] = CUtil::translit($ar["NAME"], LANGUAGE_ID); >> > return trim(implode("/", $arPath).$element_name, "/"); > function ElementAddHandler($arFields) < //if($GLOBALS["IBLOCK_ID"] == $IBLOCK_ID) //< $oElement = new CIBlockElement(); $oElement->Update($arFields["ID"], array("CODE" => "recalculate")); //> > function ElementUpdateHandler($arFields) < //if($GLOBALS["IBLOCK_ID"] == $IBLOCK_ID) //< if($rs = CIBlockElement::GetByID($arFields["ID"])) < if($ar = $rs->Fetch()) < $arFields["CODE"] = CSubsections::GetCode( $ar["IBLOCK_ID"], $ar["IBLOCK_SECTION_ID"], $ar["NAME"] ); >> //> > function SectionAddHandler($arFields) < //if($GLOBALS["IBLOCK_ID"] == $IBLOCK_ID) //< $oSection = new CIBlockSection(); $oSection->Update($arFields["ID"], array("CODE" => "recalculate")); //> > function SectionUpdateHandler($arFields) < //if($GLOBALS["IBLOCK_ID"] == $IBLOCK_ID) //< $arFields["CODE"] = CSubsections::GetCode( $arFields["IBLOCK_ID"], $arFields["ID"] ); //>> function Recalculate($iblock_id) < if(CModule::IncludeModule("iblock")) < $oSection = new CIBlockSection(); if($rs = CIBlockSection::GetList(array(), array("IBLOCK_ID" =>$iblock_id), false, array("ID"))) < while($ar = $rs->Fetch()) < $oSection->Update($ar['ID'], array("CODE" => "recalculate")); > > $oElement = new CIBlockElement(); if($rs = CIBlockElement::GetList(array(), array("IBLOCK_ID" => $iblock_id), false, false, array("ID"))) < while($ar = $rs->Fetch()) < $oElement->Update($ar['ID'], array("CODE" => "recalculate")); > > > > > AddEventHandler("iblock", "OnAfterIBlockElementAdd", array("CSubsections", "ElementAddHandler")); AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", array("CSubsections", "ElementUpdateHandler")); AddEventHandler("iblock", "OnAfterIBlockSectionAdd", array("CSubsections", "SectionAddHandler")); AddEventHandler("iblock", "OnBeforeIBlockSectionUpdate", array("CSubsections", "SectionUpdateHandler")); CSubsections::InitParser(); ?>
2. Перед кодом вызова компонента «Каталог» вставляем:
3. В шаблоне компонента «Каталог» создаём(если не создан) файл result_modifier.php (например, в папке «/bitrix/components/bitrix/catalog/templates/.default/» ) с содержимым:
Чтобы пересчитать все символьные коды элементов и разделов определённого инфоблока, в «Настройки — Инструменты — Командная PHP-строка» достаточно выполнить код:
CSubsections::Recalculate($IBLOCK_ID);
где $IBLOCK_ID — ID требуемого инфоблока. Стоит учитывать, что если в инфоблоке достаточно много элементов и разделов, то метод может не успеть выполнится до истечения лимита. В этом случае Вам понадобится самостоятельно писать пошаговый скрипт.
В обработчиках изменения/добавления разделов и элементов инфоблока, скорее всего, Вам необходимо будет указать условия выполнения кода для конкретного инфоблока.
Также, обратите внимание на то, что в файле «/bitrix/php_interface/init.php» вызывается метод CSubsections::InitParser(), который инициализирует обработчик события «OnEndBufferContent». Этот обработчик заменяет все «urlencode’нные» ядром символы «/» обратно. Это не совсем правильно, но избавляет от создания многочисленных файлов result_modifier.php для всех компонентов, выводящих ссылки на разделы и элементы, а это все простые компоненты, входящие в состав комплексного компонента «Каталог», компоненты модуля «Поиск» и т.д.
Вывести id инфоблока по URL
Ситуация такая: есть интернет-магазин. В нем из разных инфоблоков типа «Каталог» выводится список товаров в разных категориях. Инфоблок с именем «n» выводится в категории «n». Но в этом инфоблоке есть папки (подкатегории), а в папках уже находится товар.
Например:
Инфоблок: ПК и оргтехника;
Папка: Apple;
Товар: Apple IPad 2;
Но компонент для вывода каталога сделан так, что в параметры вывода можно ввести только один id — одного инфоблока. И только из него он будет выводить товар. Если попытаться вывести товар из другого инфоблока — получим пустой экран.
Я решил эту проблему с помощью переменной. Ей присваивается определенный id, в зависимости от url.
Например:
if (($true_url == '/catalog/Aksessuary_dlja_foto_videokamer/') || ($true_url == '/catalog/Videokamery/') || ($true_url == '/catalog/Fotoapparaty_cifrovye/') || ($true_url == '/catalog/Fotobumaga/')) $iBlock_id = 16; //это id инфоблока
Да, я знаю что это очень криво, и даже смешно. И проблема тут ещё в том, что при таком условии компонент выводит информацию только в том случае, если присутствуют именно эти url’ы. А значит что товары посмотреть будет проблемно, т.к. их очень много, и прописывать url каждого достаточного проблемно.
Нужно как-то вывести информацию об инфоблоке в массив, в зависимости от url, на котором мы сейчас находимся, не прописывая по десять раз URL’ы.
Как это можно осуществить?
