Телеграм: @camouf_ru Почта: mihail@bazarow.ru

Пункты меню из разделов инфоблока Битрикс

Просмотров: 88786

В принципе это стандартная возможность системы управления битрикс, но почему-то часто спрашивают как это сделать. Возможно в документации данный вопрос освещен не достаточно понятно. Постараюсь рассказать по простому, со скринами.

Добавляем разделы в инфоблок:

Предположим что нам нужно создать меню из подкатегорий новостей. У нас уже есть готовый инфоблок для новостей и он выведен на сайт. В общем новости работают. И наступил момент, что новостей стало достаточно много и пора их разбить на несколько категорий: "Спорт", "Финансы" и.т.д.

Для начала создаем эти разделы:

создание раздела в инфоблоке битрикс

Теперь задача создать пункты выпадающего меню, которое автоматически будет брать разделы в качестве своих пунктов. Для этого нужно создать необходимый тип меню в Управлении структурой. В моем случае я создаю тип меню "Меню подраздела"

создание меню

Создаем в нужном каталоге сайта этот тип меню и рядом с ним создаем такой же файл с приставкой _ext.php.

Создание ext меню

В моем примере я создаю блог на основе компонента новостей, потому каталог и соответствующий инфоблок называются blog

Настройка ext меню в битрикс

В меню сайта необходимо подключить соответствующее меню в пункте "Тип меню для остальных уровней:" и установить чекбокс для "Подключать файлы с именами вида .тип_меню.menu_ext.php:"

ext меню

В наше ..._ext.php меню вносим вот такие данные:

 <? 
 if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); 
      global $APPLICATION; 
      $aMenuLinksExt=$APPLICATION->IncludeComponent("bitrix:menu.sections", "", array( 
      "IS_SEF" => "Y", 
      "SEF_BASE_URL" => "/blog/", 
      "SECTION_PAGE_URL" => "#SECTION_ID#/", 
      "DETAIL_PAGE_URL" => "#SECTION_ID#/#ELEMENT_ID#.html", 
      "IBLOCK_TYPE" => "company", 
      "IBLOCK_ID" => "5", 
      "DEPTH_LEVEL" => "3", 
      "CACHE_TYPE" => "A", 
      "CACHE_TIME" => "36000000" 
      ), 
  false 
 ); 
 $aMenuLinks = array_merge($aMenuLinksExt, $aMenuLinks); 
 ?> 

Где:

  • "SEF_BASE_URL" => "/blog/", - каталог инфоблока на сайте
  • "SECTION_PAGE_URL" => "#SECTION_ID#/", - подставляем ID раздела
  • "DETAIL_PAGE_URL" => "#SECTION_ID#/#ELEMENT_ID#.html", - полный путь к элементу инфоблока
  • "IBLOCK_TYPE" => "company", - ID типа инфоблока из которого выводим
  • "IBLOCK_ID" => "5", ID инфоблока из которого выводим
  • "DEPTH_LEVEL" => "4", уровень вложенности, этой цифрой можно выводить подразделы разделов если иерархия многоуровневая

В настройках компонента инфоблока также прописываем аналогичный путь к элементам и разделам инфоблока

настройка ЧПУ битрикс

В итоге все вновь создаваемые разделы инфоблока будут автоматически попадать в выпадающее меню (в моем случае, вы можете проделать эти манипуляции для любого типа меню)

Надеюсь объяснил наглядно и понятно, если остались вопросы или есть чем дополнить данную записку, прошу писать в комментариях. Всем успехов.

Элементы инфоблока в меню

Таким же образом можно сделать и меню из элементов инфоблока или вообще чего угодно. Просто, в файле меню с типом _ext наполняете массив $aMenuLinksExt нужными данными

Что бы получить элементы и их ссылки достаточно воспользоваться методом CIBlockElement::GetList

Быстрый пример:


if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
global $APPLICATION;
if(CModule::IncludeModule("iblock")) {
   $res = CIBlockElement::GetList(
             false, 
             array(
                "IBLOCK_ID"=> 5, // ID нужного инфоблока
                "ACTIVE"=>"Y"
             ),
            false,
            false, 
            array( // Нужны только названиеи ссылка
                "NAME"
                "DETAIL_PAGE_URL"
             ),
   );
   while($arFields = $res->Fetch()){
           $aMenuLinksExt[] = Array(
                $arFields['NAME'],
                $arFields['DETAIL_PAGE_URL'],
                Array(),
                Array(),
                ""
             );
    }
}
$aMenuLinks = array_merge($aMenuLinksExt, $aMenuLinks);
Михаил Базаров 21.02.2019
Цитата
olegrus написал:
Михаил подскажите а как добавить произвольную свою ссылку в выпадающем меню с разделами из каталога
Просто добавить в меню, там массив собирается:
$aMenuLinksExt - массив с разделами
$aMenuLinks - массив с произвольными пунктами меню
Код
$aMenuLinks = array_merge($aMenuLinksExt, $aMenuLinks);
olegrus 21.02.2019
Михаил подскажите а как добавить произвольную свою ссылку в выпадающем меню с разделами из каталога
Виталий Близнецов 26.01.2019
Проблема была в том, что установщик  переписал некоторые файлы инфоблоков. Перезаписали эти файлы и все заработало.
Спасибо, Михаил, за полезный блог!
Виталий Близнецов 20.01.2019
не работает не только меню, на главной странице новость не открывается
https://www.leto-navsegda.ru/#SITE_DIR#/catalog/chasovoy-poyas-kryma/

здесь эта новость открывается https://www.leto-navsegda.ru/events/789232/
Виталий Близнецов 20.01.2019
Пересоздал, но проблема осталась, через меню ссылки не работают.  
На всех сайтах http://polmira82.ru/#SITE_DIR#catalogdariano
https://www.leto-navsegda.ru/catalog/alushta/#SITE_DIR#catalogalupka
https://feokazanok.ru/?back_url_admin=%2Fbitrix%2Fadmin%2Furlrewrite_list.php%3Flang%3Dru#SITE_DIR#catalogprofoborudovanie_dlya_oshchepita/kartofelechistki_ele­ktricheskie


Причем,  все эти сайты работают на разных шаблонах

Спасибо!!!
Михаил Базаров 20.01.2019
Цитата
Виталий Близнецов написал:
Доброго времени суток, Михаил.
У меня многосайтовая  установка Битрикс, при добавлении очередного сайта произошла следующая ситуация, я авторизовался на сайте №1 и установил шаблон для сайта №2. В связи  с чем у меня на всех сайтах слетели частично адреса страниц.  Перестали работать на всех сайтах "Левое меню."  
ЧПУ отключил.
В  пути к элементу инфоблока стало добавляются значения "#SITE_DIR#catalog"  . Вот эта ссылка не работает , при входе через меню   http://feokazanok.ru/#SITE_DIR#catalogavto_i_moto

вот настройки в файле .left.menu_ext.php

                    "IS_SEF" => "N",
        "SEF_BASE_URL" => "/catalog/",
        "SECTION_PAGE_URL" => "#SECTION_ID#/",
       "DETAIL_PAGE_URL" => "#SECTION_ID#/#ELEMENT_ID#.html",
        "IBLOCK_TYPE" => "/catalog/",

Если захожу  на этой странице через комплексный компонент "bitrix.catalog" , то страница открывается  http://feokazanok.ru/?SECTION_ID=30692


Заранее благодарен!
У Вас там сайт вообще не открывается.
Но попробуйте (предварительно сохранившись) - пересоздать правила обработки адресов, в настройках главного модуля.
Виталий Близнецов 20.01.2019
Доброго времени суток, Михаил.
У меня многосайтовая  установка Битрикс, при добавлении очередного сайта произошла следующая ситуация, я авторизовался на сайте №1 и установил шаблон для сайта №2. В связи  с чем у меня на всех сайтах слетели частично адреса страниц.  Перестали работать на всех сайтах "Левое меню."  
ЧПУ отключил.
В  пути к элементу инфоблока стало добавляются значения "#SITE_DIR#catalog"  . Вот эта ссылка не работает , при входе через меню  http://feokazanok.ru/#SITE_DIR#catalogavto_i_moto

вот настройки в файле .left.menu_ext.php

                    "IS_SEF" => "N",
        "SEF_BASE_URL" => "/catalog/",
        "SECTION_PAGE_URL" => "#SECTION_ID#/",
       "DETAIL_PAGE_URL" => "#SECTION_ID#/#ELEMENT_ID#.html",
        "IBLOCK_TYPE" => "/catalog/",

Если захожу  на этой странице через комплексный компонент "bitrix.catalog" , то страница открывается http://feokazanok.ru/?SECTION_ID=30692


Заранее благодарен!
Салман Курбанов 10.08.2018
Код
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
   global $APPLICATION;

   if(CModule::IncludeModule("iblock"))
   {

   $IBLOCK_ID = 5; // указываем из какого инфоблока берем элементы

   $arOrder = Array("NAME"=>"ASC"); // сортируем по свойству SORT по возрастанию
   $arSelect = Array("ID", "NAME", "IBLOCK_ID","DETAIL_PAGE_URL", 'PREVIEW_PICTURE', 'DETAIL_PICTURE');
   $arFilter = Array("IBLOCK_ID"=>$IBLOCK_ID, "ACTIVE"=>"Y", "PROPERTY_razdel"=> $_REQUEST["SECTION_ID"]);
   $res = CIBlockElement::GetList($arOrder, $arFilter, false, false, $arSelect);

   while($ob = $res->GetNextElement())
   {
   $arFields = $ob->GetFields(); // берем поля
   //echo $arFields['NAME']." - arFields['NAME']<br>";
   // echo '<pre>';
   //print_r($arFields);     
   //echo '</pre>'; 

   // начинаем наполнять массив aMenuLinksExt нужными данными
   $aMenuLinksExt[] = Array(
   $arFields['NAME'],
   $arFields['DETAIL_PAGE_URL'],
   $arFields['PREVIEW_PICTURE'],
   $arFields ['DETAIL_PICTURE'],   
   Array(),
   Array(),
   ""
   );

   } // while($ob = $res->GetNextElement())

   }//  if(CModule::IncludeModule("iblock"))

   // echo "<br>Массив aMenuLinksExt - дополнительный";
   //echo '<pre>';
   //print_r($aMenuLinksExt);
   //echo '</pre>'; 

   $aMenuLinks = array_merge($aMenuLinksExt, $aMenuLinks);
      print_r($aMenuLinksExt);
 ?>
такой код у меня в .лефт.меню.пхп передает элементы инфоблока в $aMenuLinksExt добавил от себя
Код
   $arFields['PREVIEW_PICTURE'], 
$arFields ['DETAIL_PICTURE'],
в масивее $aMenuLinksExt картинки присутствуют но в шаблоне меню в масиве $arResult нету их помогите пожалуйста. куда передаются данные из $aMenuLinksExt
Михаил Базаров 01.08.2018
Цитата
Салман Курбанов написал:
здраствуйте а как выделить пункт на странице которой находишься
Просто добавить какой-нибудь класс к активному пункту и стилизовать через css

Посмотрите как это сделано в типовом меню и по аналогии
Салман Курбанов 01.08.2018
Цитата
Салман Курбанов пишет:
здраствуйте а как выделить пункт на странице которой находишься
для левого меню каталога товаров
Салман Курбанов 01.08.2018
здраствуйте а как выделить пункт на странице которой находишься
dem 09.07.2018
Цитата
Михаил Базаров пишет:
Такие разделы, если их нет возможности вынести в отдельный инфлоблок, можно попробовать скрыть на уровне шаблона. Например, проверяя ссылку.
В настоящее время у меня выведены SEO страницы в отдельный  инфоблок, но это жутко раздражает. Тем более, что если делать в рамках одного инфоблока, проще вывести таблицу с элементами. В задаче SEO ссылка должна быть внутри главного подраздела (какого либо вида товара). Поэтому пока не представляю как можно отсортировать по ссылке. Опять же надо еще убрать ссылки с компонента Каталог. Попробую все таки отфильтровать через пользователькое поле к разделу "Скрыть в меню". Есть галка - скрываем, нет галочки - показываем.
Михаил Базаров 09.07.2018
Цитата
dem написал:
Цитата
Михаил Базаров  пишет:
Цитата
dem написал:
Михаил, возможно повторюсь...
Нужно скрыть из меню некоторые разделы (например с seo статьями). То есть раздел активный, но его не должно быть в меню.
Как лучше реализовать? Пользовательское поле делать: отражать/не отражать в меню?
Да нет, можно просто не добавлять в меню. Физически пусть будет раздел, но меню это просто компонент который берет пункты из файла ТИП_МЕНЮ.menu.php - в нем удалите да и все
Не совсем понял как можно удалить. Разделы же подгружаются автоматически из массива данных. В файле ТИП_МЕНЮ.menu.php нечего удалять.
А пардон) Не учел что тема про меню из разделов. Такие разделы, если их нет возможности вынести в отдельный инфлоблок, можно попробовать скрыть на уровне шаблона. Например, проверяя ссылку.

Что-то вроде (пишу быстро, там додумаете)
Код
<?if ($arResult['LINK'] !== '/путь/ссылки/'){?> Пункт меню выводится <?}?>
dem 09.07.2018
Цитата
Михаил Базаров пишет:
Цитата
dem написал:
Михаил, возможно повторюсь...
Нужно скрыть из меню некоторые разделы (например с seo статьями). То есть раздел активный, но его не должно быть в меню.
Как лучше реализовать? Пользовательское поле делать: отражать/не отражать в меню?
Да нет, можно просто не добавлять в меню. Физически пусть будет раздел, но меню это просто компонент который берет пункты из файла ТИП_МЕНЮ.menu.php - в нем удалите да и все
Не совсем понял как можно удалить. Разделы же подгружаются автоматически из массива данных. В файле ТИП_МЕНЮ.menu.php нечего удалять.
Михаил Базаров 09.07.2018
Цитата
dem написал:
Михаил, возможно повторюсь...
Нужно скрыть из меню некоторые разделы (например с seo статьями). То есть раздел активный, но его не должно быть в меню.
Как лучше реализовать? Пользовательское поле делать: отражать/не отражать в меню?  
Да нет, можно просто не добавлять в меню. Физически пусть будет раздел, но меню это просто компонент который берет пункты из файла ТИП_МЕНЮ.menu.php - в нем удалите да и все
dem 08.07.2018
Михаил, возможно повторюсь...
Нужно скрыть из меню некоторые разделы (например с seo статьями). То есть раздел активный, но его не должно быть в меню.
Как лучше реализовать? Пользовательское поле делать: отражать/не отражать в меню?
Михаил Базаров 04.03.2018
Цитата
Lu Sh написал:
Добрый день! Михаил, благодарю вас за ваш труд и помощь новичкам!
Подскажите как осуществить такую задачу:

Меню из разделов и подразделов инфоблока.
Разделы должны быть на главной, при нажатии на раздел переходим на другую страницу, где:
- только название раздела, по которому перешли и только его подразделы.

Подразделы больше никуда не ведут у них ссылки-якоря.

Есть ли в ваших уроках пример меню такого вида? Заранее благодарю.  
Это можно сделать штатными средствами, просто используйте комплексный компонент "Каталог", он так и работает: выводить подразделы текущего раздела (в котором пользователь)
Lu Sh 04.03.2018
Добрый день! Михаил, благодарю вас за ваш труд и помощь новичкам!
Подскажите как осуществить такую задачу:

Меню из разделов и подразделов инфоблока.
Разделы должны быть на главной, при нажатии на раздел переходим на другую страницу, где:
- только название раздела, по которому перешли и только его подразделы.

Подразделы больше никуда не ведут у них ссылки-якоря.

Есть ли в ваших уроках пример меню такого вида? Заранее благодарю.
Последовательность Возвратная 10.02.2018
Вот мой файл ext из нужного каталога, он немного отличается, поэтому я туплю, простите. Внизу две строчки - это я понимаю сборка ссылок, как мне туда добавить этот код, чтоб получился новый независимый подпункт меню?
Код
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
if(!CModule::IncludeModule("iblock")) return;

global $APPLICATION;

$iBlock = 22;
$arOrder = Array("SORT" => "ASC");
$arFilter = Array('IBLOCK_ID' => $iBlock);
$bIncCnt = false;
$Select = Array('NAME', 'SECTION_PAGE_URL', 'ID');
$NavStartParams = false;

$arRes = CIBlockSection::GetList($arOrder, $arFilter, $bIncCnt, $Select, $NavStartParams);

$arr = array();

while ($value = $arRes->GetNext()) {
   $arr[] = array($value['NAME'], $value['SECTION_PAGE_URL'],
            '3' => array('DEPTH_LEVEL' => 2)
         );
   
   $arOrder2 = Array("SORT"=>"ASC");
   $arFilter2 = Array('IBLOCK_ID' => $iBlock, 'SECTION_ID' => $value['ID']);
   $arGroupBy2 = false;
   $arNavStartParams2 = false;
   $arSelectFields2 = Array('NAME', 'DETAIL_PAGE_URL', 'DETAIL_PICTURE');

   $arElements = CIBlockElement::GetList($arOrder2, $arFilter2, $arGroupBy2, $arNavStartParams2, $arSelectFields2);
   $arr2 = array();

   while ($value2 = $arElements->GetNext()) {
      
      // $rsFile = CFile::GetPath($value2['DETAIL_PICTURE']);
      // $arFile = $rsFile->Fetch();
      $file = CFile::ResizeImageGet($value2['DETAIL_PICTURE'], array('width'=>200, 'height'=>144), BX_RESIZE_IMAGE_PROPORTIONAL, false); 


      $arr2[] = array($value2['NAME'], $value2['DETAIL_PAGE_URL'],
            '3' => array('DEPTH_LEVEL' => 3, 'DETAIL_PICTURE' => $file['src'])
         );
   }
   $aMenuLinks = array_merge($aMenuLinks, $arr);
   $aMenuLinks = array_merge($aMenuLinks, $arr2);
   unset($arr, $arr2);
}

?>
Михаил Базаров 10.02.2018
Цитата
Последовательность Возвратная написал:
 
В моем варианте нет чекбокса "Создать пункт меню"...
https://yadi.sk/i/a6g5IJ273SFZ4x  (если скрин не прикрепится)

Просто в ручную добавте
Код
<?
$aMenuLinks = Array(
   Array(
      "Новый раздел", 
      "/nww/", 
      Array(), 
      Array(), 
      "" 
   )
);
?>

Работы из портфолио

В портфолио не публикуются работы, доля моего участия в которых менее 80%.
Часто обращаются за доработками уже существующих проектов или реализацией не стандратного функционала на готовых сайтах.