Часто возникает необходимость вывести разделы инфоблока с элементами на одной странице. Для этой цели подойдет связка catalog.sections + news.list. Или можно обойтись одним bitrix:news.list, немного кастомизировав шаблон компонента. Пойдем вторым путем.
Итак.
- Размещаем компонент bitrix:news.list на целевой странице.
- Копируем шаблон компонента в текущий шаблон сайта.
- Создаем в нем файл result_modifier.php с таким содержимым.
// Получаем все активные разделы ИБ
$rsSections = CIBlockSection::GetList(
Array("SORT" => "ASC"),
Array(
"=IBLOCK_ID" => $arParams["IBLOCK_ID"],
"=ACTIVE" => "Y"
)
);
// Собираем разделы в массив
while ($arSection = $rsSections->GetNext())
$arSections[] = $arSection;
// Фильтруем элементы по принадлежности к разделу
// Получаем итоговый массив со структурой: [SECTION] => [ELEMENTS]
foreach ($arSections as $arSection){
foreach ($arResult["ITEMS"] as $arItem){
if ($arItem["IBLOCK_SECTION_ID"] == $arSection["ID"])
$arSection["ELEMENTS"][] = $arItem;
}
$arElementGroups[] = $arSection;
}
$arResult["ITEMS"] = $arElementGroups;
В итоге получаем такую структуру:
Array
(
// Разделы
[0] => Array
(
[ID] => 17
[NAME] => Юридические вопросы
[CODE] => yuridicheskie-voprosy
[SECTION_PAGE_URL] => /faq/yuridicheskie-voprosy/
[ELEMENTS] => Array
(
// Элементы
[0] => Array
[1] => Array
[2] => Array
)
)
[1] => Array
[2] => Array
...
)
В template.php выводим так:
<?foreach ($arResult["ITEMS"] as $arSection):?>
<h4><?=$arSection["NAME"]?></h4>
<?if ($arSection["ELEMENTS"]):?>
<ul>
<?foreach ($arSection["ELEMENTS"] as $arItem):?>
<?
$this->AddEditAction($arItem['ID'], $arItem['EDIT_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_EDIT"));
$this->AddDeleteAction($arItem['ID'], $arItem['DELETE_LINK'], CIBlock::GetArrayByID($arItem["IBLOCK_ID"], "ELEMENT_DELETE"), array("CONFIRM" => GetMessage('CT_BNL_ELEMENT_DELETE_CONFIRM')));
?>
<li id="<?=$this->GetEditAreaId($arItem['ID']);?>">
<a href="<?=$arItem["DETAIL_PAGE_URL"]?>"><?=$arItem["NAME"]?></a>
</li>
<?endforeach?>
</ul>
<?endif?>
<?endforeach?>
Не нравится мне имя ключа $arResult["ITEMS"], напрашивается "SECTIONS", но пока оставлю, как есть.
Однако есть вариант лучше, который избавит нас от вложенного foreach.
$rsSections = CIBlockSection::GetList(
Array("SORT" => "ASC"),
Array(
"=IBLOCK_ID" => $arParams['IBLOCK_ID'],
"=ACTIVE" => "Y"
)
);
// Тут вместо инкрементного индекса, ID раздела
while ($arSection = $rsSections->GetNext())
$arSections[$arSection['ID']] = $arSection;
// По нему производим неявную фильрацию
foreach($arResult["ITEMS"] as $arItem) {
$arSections[$arItem['IBLOCK_SECTION_ID']]['ITEMS'][] = $arItem;
}
$arResult["SECTIONS"] = $arSections;
Получаем струтуру вида:
Array
(
// Разделы
[18] => Array
(
[ID] => 18
[NAME] => Вопросы по доставка и оплате
[CODE] => voprosy-po-dostavka-i-oplate
[SECTION_PAGE_URL] => /faq/voprosy-po-dostavka-i-oplate/
[IBLOCK_TYPE_ID] => references
[ITEMS] => Array
(
// Элементы
[0] => Array
(
[ID] => 331
[IBLOCK_SECTION_ID] => 18
[NAME] => Как изменить номер телефона в личном кабинете?
[DETAIL_PAGE_URL] => /faq/voprosy-po-dostavka-i-oplate/kak-izmenit-nomer-telefona/
)
[1] => Array
[2] => Array
В template.php аналогичная верстка, лишь переименуем ключи $arResult.
<?foreach ($arResult["SECTIONS"] as $arSection):?>
<h4><?=$arSection["NAME"]?></h4>
<ul>
<?foreach ($arSection["ITEMS"] as $arItem):?>
<li id="<?=$this->GetEditAreaId($arItem['ID']);?>">
<a href="<?=$arItem["DETAIL_PAGE_URL"]?>"><?=$arItem["NAME"]?></a>
</li>
<?endforeach?>
</ul>
<?endforeach?>
-- Написано на основе данных постов:
Можно ли таким образом вывести картинку для анонса раздела или детальную картинку раздела? В структуре имеется только [PICTURE].
Как добиться такого варианта:
<img src="<?= $arSection['PICTURE']['SRC'] ?>" alt="" />
по аналогии с картинками элементов?
Т.е., как получить путь к картинкам разделов и вывести их в шаблоне?
Спасибо!