В проектах на 1С-Битрикс с шаблонами Aspro часто возникает задача: вывести отдельные подразделы каталога (второго уровня) на первый уровень — например, в меню или в списке разделов.
При этом важно сохранить:
- структуру URL (вложенность разделов)
- привязку к родителю в инфоблоке
- корректную сортировку
В этой статье рассмотрим два решения:
- для меню каталога
- для списка разделов (catalog.section.list)
1. Задача

Есть структура каталога:
- Швейное оборудование
- Оверлоки (overloki)
- Распошивальные машины (rasposhivalnye_mashiny)
Нужно:
- оставить структуру как есть (для SEO и URL)
- но вывести эти разделы как будто они находятся в первом уровне
2. Решение для меню каталога (Aspro Max / Next)
Решение реализуется в result_modifier.php меню.
Логика:
- находим нужные разделы во втором уровне
- удаляем их из вложенности
- добавляем в первый уровень
- вставляем по SORT из инфоблока
Код решения
// какие разделы поднимаем
$promoteSectionCodes = array(
'overloki',
'rasposhivalnye_mashiny',
);
// получить код раздела из пункта меню
function getMenuSectionCode($item){
if (!empty($item['PARAMS']['CODE'])) return $item['PARAMS']['CODE'];
if (!empty($item['PARAMS']['SECTION_CODE'])) return $item['PARAMS']['SECTION_CODE'];
if (!empty($item['CODE'])) return $item['CODE'];
if (!empty($item['LINK'])) {
$path = trim(parse_url($item['LINK'], PHP_URL_PATH), '/');
$parts = explode('/', $path);
return end($parts);
}
return '';
}
// получить SORT из инфоблока
function getSectionSort($iblockId, $code){
static $cache = [];
$key = $iblockId.'|'.$code;
if (isset($cache[$key])) return $cache[$key];
$res = CIBlockSection::GetList([], [
'IBLOCK_ID' => $iblockId,
'CODE' => $code,
'GLOBAL_ACTIVE' => 'Y'
], false, ['SORT']);
if ($row = $res->Fetch()) {
return $cache[$key] = (int)$row['SORT'];
}
return $cache[$key] = 500;
}
// перенос
foreach ($arResult as $rootKey => $rootItem) {
if (empty($rootItem['CHILD'])) continue;
$promoted = [];
foreach ($rootItem['CHILD'] as $parentKey => $parentItem) {
if (empty($parentItem['CHILD'])) continue;
foreach ($parentItem['CHILD'] as $childKey => $childItem) {
$code = getMenuSectionCode($childItem);
if (in_array($code, $promoteSectionCodes)) {
$promoted[$code] = $childItem;
unset($arResult[$rootKey]['CHILD'][$parentKey]['CHILD'][$childKey]);
}
}
}
foreach ($promoteSectionCodes as $code) {
if (!isset($promoted[$code])) continue;
$item = $promoted[$code];
$sort = getSectionSort($item['PARAMS']['IBLOCK_ID'], $code);
$insertIndex = count($arResult[$rootKey]['CHILD']);
foreach ($arResult[$rootKey]['CHILD'] as $i => $lvl1) {
$lvlCode = getMenuSectionCode($lvl1);
$lvlSort = getSectionSort($item['PARAMS']['IBLOCK_ID'], $lvlCode);
if ($lvlSort > $sort) {
$insertIndex = $i;
break;
}
}
array_splice($arResult[$rootKey]['CHILD'], $insertIndex, 0, [$item]);
}
break;
}

3. Решение для списка разделов (catalog.section.list)
В компоненте catalog.section.list нужные разделы часто просто не попадают в результат.
Поэтому здесь применяется другая стратегия:
- загружаем нужные разделы напрямую из инфоблока
- добавляем их в массив верхнего уровня
- вставляем по SORT
Код решения
$promoteSectionCodes = array(
'overloki',
'rasposhivalnye_mashiny',
);
$additionalSections = [];
$rs = CIBlockSection::GetList(
['SORT' => 'ASC'],
[
'IBLOCK_ID' => $arParams["IBLOCK_ID"],
'CODE' => $promoteSectionCodes,
'GLOBAL_ACTIVE' => 'Y',
],
false,
['ID','NAME','CODE','SORT','PICTURE','SECTION_PAGE_URL']
);
while($sec = $rs->GetNext()) {
$sec["SECTION_PAGE_URL"] = CIBlock::ReplaceDetailUrl(
$sec["SECTION_PAGE_URL"],
$sec,
false,
'S'
);
$sec["DEPTH_LEVEL"] = 1;
$sec["SECTIONS"] = [];
$additionalSections[$sec["CODE"]] = $sec;
}
$top = array_values($arResult["SECTIONS"]);
foreach ($promoteSectionCodes as $code) {
if (!isset($additionalSections[$code])) continue;
$new = $additionalSections[$code];
$sort = (int)$new['SORT'];
$insertIndex = count($top);
foreach ($top as $i => $item) {
$itemSort = isset($item['SORT']) ? (int)$item['SORT'] : 500;
if ($itemSort > $sort) {
$insertIndex = $i;
break;
}
}
array_splice($top, $insertIndex, 0, [$new]);
}
$arResult["SECTIONS"] = $top;
4. Важные моменты
- Решение не изменяет структуру инфоблока
- URL остаются вложенными (SEO не страдает)
- Сортировка берется из реального поля SORT
- Работает отдельно для меню и отдельно для списка разделов
5. Итог
Таким образом можно гибко управлять отображением каталога без изменения структуры данных:
- в меню — через модификацию массива
- в списке разделов — через догрузку элементов
Это универсальный подход для Aspro Max и Aspro Next.



