Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Апрель Интернет: нюансы создания сайтов Выпуск первый, с введением и программистским началом


Введение к рассылке

В этой новой рассылке мы планируем без особой систематичности публиковать статьи, соображения, полезные советы в деле создания и поддержке веб-сайтов. Список статей будет также пополняться на сайте Апрель Интернет: http://www.sunbow.ru/services/, где вы сможете найти сопутствующую теме информацию.

Сейчас Апрель Интернет использует в создании сайтов для своих заказчиков систему управления сайтами Битрикс, поэтому основная часть статей, видимо, будет о ней. Преимущественно — как видоизменить тот или иной компонент, чтобы он обладал нужной функциональностью. Это из разряда программирования, но наверное будем писать и о дизайне в целом (здесь дизайн не только как изобразительная деятельность, но шире — конструирование сайта в разных аспектах). Поэтому пусть вас, если вы не программист на PHP, не смущает программистская направленность первых выпусков — будут выпуски и не программистские.

Видимо, на страницах этой рассылки нет нужды говорить в целом о Битрикс — это легко найти на сайте разработчика.

Кто же знает что такое Битрикс и делает на ней сайты, видимо, сможет оценить первую статью рассылки — о том как поправить стандартный компонент древовидного иерархического меню, чтобы оно вело себя правильно: чтобы подсвечивался активный пункт и открывался раздел, этот пункт содержащий.

Изготовление древовидного иерархического меню на базе структуры разделов инфоблока

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

Исходные материалы:
Стандартный компонент bitrix:menu -- выводит меню из заданного файла по заданному шаблону.
Стандартный компонент bitrix:menu.sections -- дополняет любое меню списком разделов заданного инфоблока.

Задача состоит именно в модификации поведения древовидного меню, поэтому опустим стандартные процедуры подключения компонентов в шаблоне сайта.

Итак, посмотрим, что передает компонент bitrix:menu в свой шаблон (в нашем случае tree ).

Для этого добавим в шаблон конструкцию

<?  echo "<pre>"; print_r($arResult); echo "</pre>"; ?>

Видим, что массив $arResult, содержит вот такую колбасу:

Array
   (
 [0] => Array
 (
 [TEXT] => Все
 [LINK] => /sunplace/index.php
 [SELECTED] => 
 [PERMISSION] => X
 [ADDITIONAL_LINKS] => Array
 (
 )
 [ITEM_TYPE] => P
   [ITEM_INDEX] => 0
   [PARAMS] => Array
   (
   )
 [DEPTH_LEVEL] => 1
   [IS_PARENT] => 
   )
 [1] => Array
   (
   [TEXT] => Краснодарский край
   [LINK] => /sunplace/section.php?SECTION_ID=243
   [SELECTED] => 
   [PERMISSION] => X
   [ADDITIONAL_LINKS] => Array
   (
   )
 [ITEM_TYPE] => U
   [ITEM_INDEX] => 1
   [PARAMS] => Array
   (
   [FROM_IBLOCK] => 1
   [IS_PARENT] => 1
   [DEPTH_LEVEL] => 1
   )
 [DEPTH_LEVEL] => 1
   [IS_PARENT] => 1
   )
 [2] => Array
   (
   [TEXT] => Геленджик
   [LINK] => /sunplace/section.php?SECTION_ID=238
   [SELECTED] => 1
   [PERMISSION] => X
   [ADDITIONAL_LINKS] => Array
   (
   )
 [ITEM_TYPE] => U
   [ITEM_INDEX] => 2
   [PARAMS] => Array
   (
   [FROM_IBLOCK] => 1
   [IS_PARENT] => 
   [DEPTH_LEVEL] => 2
   )
 [DEPTH_LEVEL] => 2
   [IS_PARENT] => 
   )
 [3] => Array
   (
   [TEXT] => Кабардинка
   [LINK] => /sunplace/section.php?SECTION_ID=237
   [SELECTED] => 
   [PERMISSION] => X
   [ADDITIONAL_LINKS] => Array
   (
   )
 [ITEM_TYPE] => U
   [ITEM_INDEX] => 3
   [PARAMS] => Array
   (
   [FROM_IBLOCK] => 1
   [IS_PARENT] => 
   [DEPTH_LEVEL] => 2
   )
 [DEPTH_LEVEL] => 2
   [IS_PARENT] => 
   )
 [4] => Array
   (
   [TEXT] => Крым
   [LINK] => /sunplace/section.php?SECTION_ID=244
   [SELECTED] => 
   [PERMISSION] => X
   [ADDITIONAL_LINKS] => Array
   (
   )
 [ITEM_TYPE] => U
   [ITEM_INDEX] => 4
   [PARAMS] => Array
   (
   [FROM_IBLOCK] => 1
   [IS_PARENT] => 1
   [DEPTH_LEVEL] => 1
   )
 [DEPTH_LEVEL] => 1
   [IS_PARENT] => 1
   )
 [5] => Array
   (
   [TEXT] => Коктебель
   [LINK] => /sunplace/section.php?SECTION_ID=246
   [SELECTED] => 
   [PERMISSION] => X
   [ADDITIONAL_LINKS] => Array
   (
   )
 [ITEM_TYPE] => U
   [ITEM_INDEX] => 5
   [PARAMS] => Array
   (
   [FROM_IBLOCK] => 1
   [IS_PARENT] => 
   [DEPTH_LEVEL] => 2
   )
 [DEPTH_LEVEL] => 2
   [IS_PARENT] => 
   )
 [6] => Array
   (
   [TEXT] => Ялта
   [LINK] => /sunplace/section.php?SECTION_ID=245
   [SELECTED] => 
   [PERMISSION] => X
   [ADDITIONAL_LINKS] => Array
   (
   )
 [ITEM_TYPE] => U
   [ITEM_INDEX] => 6
   [PARAMS] => Array
   (
   [FROM_IBLOCK] => 1
   [IS_PARENT] => 
   [DEPTH_LEVEL] => 2
   )
 [DEPTH_LEVEL] => 2
   [IS_PARENT] => 
   )
)

Она получается при работе связки компонентов bitrix:menu и bitrix:menu.sections, причем в файле меню имеется один пункт "Все", а в соответствующем инфоблоке -- структура разделов:

Краснодарский край
Геленджик
Кабардинка
Крым
Коктебель
Ялта

Присмотревшись к $arResult, видим, что в данный момент активен раздел с "Геленджиком": [SELECTED] => 1

При этом родительский "Краснодарский край" никак не отмечен, хотя дочерний раздел "Геленджик" находится именно в нем. Именно по причине такой "неотмеченности" мы и добавим маленький алгоритм для выявления того родительского раздела меню, в котором имеется активный дочерний. Ведь нам его нужно знать, чтобы "развернуть" раздел для отображения дочерних, включая активный.

Смотрим в исходный шаблон:

<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?if (!empty($arResult)):?>
<div class="menu-sitemap-tree">
   <ul>
   <?$previousLevel = 0;foreach($arResult as $arItem):?>
 <?if ($previousLevel && $arItem["DEPTH_LEVEL"] < $previousLevel):?>
   <?=str_repeat("</ul></li>", ($previousLevel - $arItem["DEPTH_LEVEL"]));?>
   <?endif?>
 <?if ($arItem["IS_PARENT"]):?>
   <li class="close">
   <div class="folder" onClick="OpenMenuNode(this)"></div>
   <div class="item-text"><a href="<?=$arItem["LINK"]?>"><?=$arItem["TEXT"]?></a></div>
   <ul>
 <?else:?>
 <?if ($arItem["PERMISSION"] > "D"):?>
   <li>
   <div class="page"></div>
   <div class="item-text"><a href="<?=$arItem["LINK"]?>"><?=$arItem["TEXT"]?></a></div>
   </li>
   <?endif?>
 <?endif?>
 <?$previousLevel = $arItem["DEPTH_LEVEL"];?>
<?endforeach?>
<?if ($previousLevel > 1)://close last item tags?>
   <?=str_repeat("</ul></li>", ($previousLevel-1) );?>
   <?endif?>
</ul>
   </div>
   <?endif?>

Нигде ничего ни про подсветку, ни про разворачивание активных разделов.

Попробуем выяснить и запомнить активный родительский раздел или родительский раздел, содержащий активный дочерний:

<?foreach($arResult as $i => $arItem):
if ($arItem["IS_PARENT"]): //non deepest?
$Testing = $i; //next parent testing...
if ($arItem["SELECTED"] == "1"): //non deepest selected found
$arSelected[$Testing] = TRUE;
endif;
else: //deepest
if ($arItem["PERMISSION"] > "D"):
if ($arItem["SELECTED"] == "1"): //deepest selected found
$arSelected[$Testing] = TRUE;
endif;
endif;
endif;
endforeach;?>

Результатом цикла будет $arSelected, содержащий то, что нам нужно:

Array ( [1] => 1 )

В случае с активным "Геленджиком" имеем указатель на "Краснодарский край" ([ITEM_INDEX] => 1).

Теперь мы можем развернуть родительский раздел и подсветить активный -- родительский или дочерний:

<ul>
 <?$previousLevel = 0;
   foreach($arResult as $i => $arItem):?>
 <?if ($previousLevel && $arItem["DEPTH_LEVEL"] < $previousLevel):?>
 <?=str_repeat("</ul></li>", ($previousLevel - $arItem["DEPTH_LEVEL"]));?><?endif?>
 <?if ($arItem["IS_PARENT"]): //non deepest? ?>
 <li class="<?if (!$arSelected[$i]):?>close<?endif?>">
 <div class="folder" onClick="OpenMenuNode(this)"></div>
 <div class="<?if ($arItem["SELECTED"]):?>item-text-selected<?else:?>item-text<?endif?>">
 <strong>
<a href="<?=$arItem["LINK"]?>" title="<?=$arItem["TEXT"]?>"><?=$arItem["TEXT"]?></a>
 </strong></div>
 <ul>
 <?else: //deepest ?>
 <?if ($arItem["PERMISSION"] > "D"):?>
 <li><div class="page"></div>
<div class="<?if ($arItem["SELECTED"]):?>item-text-selected-deepest
    <?else:?>item-text-deepest<?endif?>">
 <strong>
<a href="<?=$arItem["LINK"]?>" title="<?=$arItem["TEXT"]?>"><?=$arItem["TEXT"]?></a>
 </strong></div></li>
 <?endif?>
 <?endif?>
 <?$previousLevel = $arItem["DEPTH_LEVEL"];?>
 <?endforeach?>
 <?if ($previousLevel > 1)://close last item tags?>
<?=str_repeat("</ul></li>", ($previousLevel-1) );?><?endif?></ul></div>

В результате получаем полный код модифицированного шаблона tree компонента bitrix:menu -- файл template.php:

<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?if (!empty($arResult)):?><div class="menu-sitemap-tree">
<?foreach($arResult as $i => $arItem):
   if ($arItem["IS_PARENT"]): //non deepest?
   $Testing = $i; //next parent testing...
   if ($arItem["SELECTED"] == "1"): //non deepest selected found
   $arSelected[$Testing] = TRUE;
   endif;
   else: //deepest
   if ($arItem["PERMISSION"] > "D"):
   if ($arItem["SELECTED"] == "1"): //deepest selected found
   $arSelected[$Testing] = TRUE;
   endif;
   endif;
   endif;
   endforeach;?>
 <?//print_r($arSelected);?>
<ul>
 <?$previousLevel = 0;
   foreach($arResult as $i => $arItem):?>
 <?if ($previousLevel && $arItem["DEPTH_LEVEL"] < $previousLevel):?>
 <?=str_repeat("</ul></li>", ($previousLevel - $arItem["DEPTH_LEVEL"]));?><?endif?>
 <?if ($arItem["IS_PARENT"]): //non deepest? ?>
 <li class="<?if (!$arSelected[$i]):?>close<?endif?>">
 <div class="folder" onClick="OpenMenuNode(this)"></div>
 <div class="<?if ($arItem["SELECTED"]):?>item-text-selected<?else:?>item-text<?endif?>">
 <strong>
<a href="<?=$arItem["LINK"]?>" title="<?=$arItem["TEXT"]?>"><?=$arItem["TEXT"]?></a>
 </strong></div>
 <ul>
 <?else: //deepest ?>
 <?if ($arItem["PERMISSION"] > "D"):?>
 <li><div class="page"></div>
<div class="<?if ($arItem["SELECTED"]):?>item-text-selected-deepest
    <?else:?>item-text-deepest<?endif?>">
 <strong>
<a href="<?=$arItem["LINK"]?>" title="<?=$arItem["TEXT"]?>"><?=$arItem["TEXT"]?></a>
 </strong></div></li>
 <?endif?>
 <?endif?>
 <?$previousLevel = $arItem["DEPTH_LEVEL"];?>
 <?endforeach?>
 <?if ($previousLevel > 1)://close last item tags?>
<?=str_repeat("</ul></li>", ($previousLevel-1) );?><?endif?></ul></div>
<?endif?>
<? // echo "<pre>"; print_r($arResult); echo "</pre>"; ?>

Ну и вносим соответствующие изменения в style.css:

div.menu-sitemap-tree a
   {
 font-size:100%; 
 font-weight: normal;
}
div.menu-sitemap-tree ul
   {
   list-style-type: none;
   margin: 0; 
   padding: 0 1em 0 0;
   }
div.menu-sitemap-tree ul ul
   {
   width: auto;
   margin:-0.75em 0 0 0;
   padding: 0 0 0 0.75em;
   }
div.menu-sitemap-tree li
   {
   margin: 0 0 -0.85em 0;
   padding:0;
   }
div.menu-sitemap-tree li li
   {
   margin: 0 0 -0.85em 0.5em; 
   padding:0;
   }
div.menu-sitemap-tree li.close ul
   {
   display: none;
   }
div.menu-sitemap-tree div.item-text a
   {
   position:relative;
   top:-19px;left:19px;
   }
div.menu-sitemap-tree div.item-text-selected a
   {
   position:relative;
   top:-19px;left:19px;
   font-weight: bold;
   text-decoration: underline;
   }
div.menu-sitemap-tree div.item-text-deepest a
   {
   position:relative;
   top:-19px;left:19px;
   text-decoration: underline;
   }
div.menu-sitemap-tree div.item-text-selected-deepest a
   {
   position:relative;
   top:-19px;left:19px;
   font-weight: bold;
   text-decoration: underline;
   }
div.menu-sitemap-tree li div.page
   {
   }
   /*Icons*/
   div.folder, div.page
   {
   background-repeat:no-repeat;
   width:17px;
   height:17px;
   vertical-align:top;
   }
   div.folder{cursor:pointer; cursor: hand;background-image:url(images/signminus.gif);}
   div.menu-sitemap-tree li.close div.folder{background-image:url(images/signplus.gif);}
   div.page{background-image:url(images/signdot.gif);}

 

Обратите внимание на signminus.gif, signplus.gif, signdot.gif -- их берем из интерфейса админки Битрикс, ну или рисуем свои.

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

www.sunbow.ru "Апрель Интернет" 2007г.
При использовании материалов статьи ссылка на источник www.sunbow.ru обязательна.


В избранное