Вывод разделов и элементов в bitrix:news.list

Часто возникает необходимость вывести разделы инфоблока с элементами на одной странице. Для этой цели подойдет связка 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?>