Добро пожаловать на сайт <БагБД>, где вы можете задавать вопросы о программировании и разработке на Битрикс и Битрикс24, и получать быстрые и квалифицированные ответы от профессионалов!

Динамическое меню на основе инфоблоков

00 голосов
7
Здравствуйте. Вопрос такой: есть тип инфоблоков, назовем их "Справочники". К этому типу относятся несколько инфоблоков, допустим "Телефоны", "Предприятия" и тд. Возможно ли строить меню на основе именно динамического списка инфоблоков выбранного типа, и передавать в параметре к выводимому компоненту (допустим списку новостей) IBLOCK_ID подобно как SECTION_ID передается в примерах на сайте? То есть нужны ссылки не на секции, а на сами инфоблоки.
спросил 14 Июль, 13 от FirstDie (120 баллов)

7 Ответы

00 голосов
Попробуйте воспользоваться функцией GetIBlockList
Код
CDBResult
GetIBlockList (
 string type, 
 mixed TypesInc = array(), 
 mixed TypesExc = array(), 
 array Order = array("SORT"=>"ASC"), 
 int cnt = 0
);

Функция возвращает активные для текущего сайта информационные блоки типа type.
ответил 14 Июль, 13 от Tigrof (260 баллов)
00 голосов
Подскажите пожалуйста, кто знает, каким образом лучше сделать такое меню:

Цитата
Чтобы скрипт выводил подуровни каталога с 3-мя уровнями вложенности в зависимости от того, в каком разделе находишься.
т.е.
раздел 1
раздел 1.1
раздел 1.1.1
раздел 1.1.2
раздел 1.1.3
раздел 1.2
раздел 1.3
раздел 2
раздел 2

- в случае, если находишься в разделе "раздел 1.1"

раздел 1
раздел 1.1
раздел 1.2
раздел 1.3
раздел 2
раздел 2

- в случае, если находишься в разделе "раздел 1"

раздел 1
раздел 2
раздел 2

- в случае, если находишься в корне инфоблока


С двумя уровнями всё довольно просто: берем из $_REQUEST SECTION_ID, и в зависимости от этого раскрываем нужный подуровень меню.
Но когда нужно открыть 3-й уровень, данный метод уже не срабатывает.
В общем, я пришел к некоторому, на мой взгляд, не рациональному решению:
Код
<?
if(CModule::IncludeModule("iblock"))
{
   // если $ID не задан или это не число, тогда 
   // $ID будет =0, выбираем корневые разделы
   $SECTION_ID = IntVal($_GET['SECTION_ID']);
   $items = GetIBlockSectionList(45, 0, Array("sort"=>"asc"));
   while($arItem = $items->GetNext())
   {
      echo '<a href='.$arItem["SECTION_PAGE_URL"].'>'.$arItem["NAME"].'</a><br>'; // вывод первого уровня
      
      $items22 = GetIBlockSectionList(45, $arItem["ID"], Array("sort"=>"asc")); //секции второго уровня
      while($arItem22 = $items22->GetNext())
      {
         if ($arItem22["ID"] == $SECTION_ID)
            $pp = 1; // вводим признак. Если ID секции второго уровня равен $SECTION_ID, то $pp=1 и в таком случае отображаются секции и второго и третьего уровня
      }
      
      if ($SECTION_ID == $arItem["ID"] || $pp == 1)
      {
         $items2 = GetIBlockSectionList(45, $arItem["ID"], Array("sort"=>"asc"));
         while($arItem2 = $items2->GetNext())
         {
            echo '&nbsp;&nbsp;<a href='.$arItem2["SECTION_PAGE_URL"].'>'.$arItem2["NAME"].'</a><br>'; // вывод второго уровня
            
            if ($SECTION_ID == $arItem2["ID"])
            {
               $items3 = GetIBlockSectionList(45, $arItem2["ID"], Array("sort"=>"asc"));
               while($arItem3 = $items3->GetNext())
               {
                  echo '&nbsp;&nbsp;&nbsp;&nbsp;<a href='.$arItem3["SECTION_PAGE_URL"].'>'.$arItem3["NAME"].'</a><br>'; // вывод 3-го уровня
               }
            }
            
         }
         $pp = 0; // Убиваем признак, чтобы не выводились секции второго уровня у всех разделов первого уровня
      }
   
   }
}
else
   ShowError("Модуль не установлен");

?>


Хотелось бы иметь какое-то универсальное решение на случай, если, к примеру, будет не 3, а 4 или 5 уровней вложенности..
Кто что может посоветовать?
ответил 02 Сен, 13 от Tigrof (260 баллов)
00 голосов
Берем по параметру SECTION_ID саму секцию.
$res = CIBlockSection::GetByID($_REQUEST["SECTION_ID"]);
$ar_res = $res->Fetch();

Далее выбираем секции, у которых DEPTH_LEVEL <(меньше) $ar_res["DEPTH_LEVEL"]:
$arFilter["<"."DEPTH_LEVEL"] = $ar_res["DEPTH_LEVEL"];
ответил 30 Ноя, 13 от rafka5 (100 баллов)
00 голосов
Спасибо.
Переделал так:
Код
<?
if(CModule::IncludeModule("iblock")) //подключаем модуль инфоблоков
{
   $res = CIBlockSection::GetByID($_REQUEST["SECTION_ID"]);
   $ar_res = $res->Fetch();
   $items = GetIBlockSectionList(45, false, Array("left_margin"=>"asc"), 0, Array("<=DEPTH_LEVEL" => $ar_res["DEPTH_LEVEL"]+1));
   while($arItem = $items->GetNext())
   {
      $padding = $ar_res["DEPTH_LEVEL"] - ($ar_res["DEPTH_LEVEL"] - $arItem["DEPTH_LEVEL"]);  // установка
      $padding = $padding*10;                                                   // отступа слева в зависимости от уровня вложенности
      echo '<p style="padding-left:'.$padding.'px;">'.$arItem["NAME"].'</p>';
   }
}
?>


Осталась проблема следующего характера:
Код
раздел 1
   раздел 1.1
     раздел 1.1.1
     раздел 1.1.2
     раздел 1.1.3
   раздел 1.2
раздел 2
раздел 3
   раздел 3.1
     раздел 3.1.1
     раздел 3.1.2
     раздел 3.1.3
   раздел 3.2
   раздел 3.3

Находясь в разделе 1.1, выводятся подразделы и у раздела 1.1 и у раздела 3.1 - т.е. у всех разделов, где есть подразделы. А нужно, чтобы подразделы выводились только у того раздела, где мы находимся..
Т.е., чтобы находясь в разделе 1.1 меню выглядело так:
Код
раздел 1
   раздел 1.1
     раздел 1.1.1
     раздел 1.1.2
     раздел 1.1.3
   раздел 1.2
раздел 2
раздел 3

Есть мысли?
ответил 13 Март, 14 от Tigrof (260 баллов)
00 голосов
Иван, день добрый, столкнулся с такой же проблемой как у вас, мне очень помог ваш код:
Код
<? 
if(CModule::IncludeModule("iblock")) 
{ 
   // если $ID не задан или это не число, тогда 
   // $ID будет =0, выбираем корневые разделы 
   $SECTION_ID = IntVal($_GET['SECTION_ID']); 
   $items = GetIBlockSectionList(45, 0, Array("sort"=>"asc")); 
   while($arItem = $items->GetNext()) 
   { 
      echo '<a href='.$arItem["SECTION_PAGE_URL"].'>'.$arItem["NAME"].'</a><br>'; // вывод первого уровня 
       
      $items22 = GetIBlockSectionList(45, $arItem["ID"], Array("sort"=>"asc")); //секции второго уровня 
      while($arItem22 = $items22->GetNext()) 
      { 
         if ($arItem22["ID"] == $SECTION_ID) 
            $pp = 1; // вводим признак. Если ID секции второго уровня равен $SECTION_ID, то $pp=1 и в таком случае отображаются секции и второго и третьего уровня 
      } 
       
      if ($SECTION_ID == $arItem["ID"] || $pp == 1) 
      { 
         $items2 = GetIBlockSectionList(45, $arItem["ID"], Array("sort"=>"asc")); 
         while($arItem2 = $items2->GetNext()) 
         { 
            echo '&nbsp;&nbsp;<a href='.$arItem2["SECTION_PAGE_URL"].'>'.$arItem2["NAME"].'</a><br>'; // вывод второго уровня 
             
            if ($SECTION_ID == $arItem2["ID"]) 
            { 
               $items3 = GetIBlockSectionList(45, $arItem2["ID"], Array("sort"=>"asc")); 
               while($arItem3 = $items3->GetNext()) 
               { 
                  echo '&nbsp;&nbsp;&nbsp;&nbsp;<a href='.$arItem3["SECTION_PAGE_URL"].'>'.$arItem3["NAME"].'</a><br>'; // вывод 3-го уровня 
               } 
            } 
             
         } 
         $pp = 0; // Убиваем признак, чтобы не выводились секции второго уровня у всех разделов первого уровня 
      } 
    
   } 
} 
else 
   ShowError("Модуль не установлен"); 

?>


Подскажите пожалуйста как можно сделать подсветку активного уровня меню ? заранее благодарю
ответил 04 Июль, 14 от CaxaZ (200 баллов)
00 голосов
Была такая же проблема, вывод содержимого каталога в виде меню, причем необходимо было раскрывать лишь третий уровень меню; сам каталог при этом мог содержать от 1 до 3 уровней, элементами находятся лишь на последнем уровне, все , что выше по уровню - секции. Такая вот постановка задачи. Прилично времени потратил на решение, скажу лишь, что на мой взгляд самым эффективным решением было выбирать все дерево секций с последующей пристыковкой элементов, все это дело находится в .xxx.menu_ext.php, в шаблоне меню происходит сокрытие "ненужных" уровней и подсветка активных пунктов. Если кому интересно - вышлю код
ответил 04 Ноя, 14 от xxZEUSxx (100 баллов)
00 голосов
Спасибо, решил проблему добавлением своих переменных в зависимости от переменных массива $arResult.
ответил 03 Март, 15 от CaxaZ (200 баллов)

Похожие вопросы

0 голосов
4 ответов
0 голосов
2 ответов
спросил 13 Фев, 14 от Blacat (260 баллов)
0 голосов
0 ответов
спросил 19 Фев, 14 от preo (120 баллов)
0 голосов
1 ответ
спросил 24 Апр, 14 от Dominik (100 баллов)
0 голосов
3 ответов