iЛаборатория » Blog Archive » Усовершенствованный компонент 1С-Битрикс bitrix:menu

Усовершенствованный компонент 1С-Битрикс bitrix:menu

2

Добрый день, дорогие читатели!

Если Вы следите за моим  twitter‘ом, то наверное, читали твит анонс, в котором я говорил про пост о 1С-Битрикс и jQuery меню. В данный момент, решил не много отдохнуть от работы и диплома, поэтому выкладываю пост.

Как видно из названия, в данном посте пойдет речь о стандартном компоненте 2.0 CMS 1С-Битрикс, который я немного усовершенствовал под свои нужды. Начну из далека, по работе дали задание, в котором требуется реализовать раскрывающиеся меню с сохранением раскрытых пунктов при переходе и реализовать все это на файлах меню (.left.menu.php). Как только я получил данное задание, задумался о том, как же реализовать меню на файлах? До этого я сталкивался только с меню строящимся из информационных блоков. Сразу бросается в глаза, что можно использовать стандартный компонент bitrix:menu, в котором есть все необходимые настройки, кроме одной: вывод полного меню на любой странице, даже после перехода.

Формулировка задачи

Во-первых, необходимо доработать компонент bitrix:menu и научить его всегда выводить выбранное меню (left) от корня сайта. Во-вторых, привязать меню на jQuery с плагином jQuery.cookie. Со вторым пунктом все намного проще, так как наработки в данном направлении уже имеются и о них я писал на блоге (пост “Меню на jQuery“). С первым в общем-то тоже проблем не было, нужно было только придумать как все красиво подправить, чтобы это работало, было удобно и можно было использовать в других проектах. С постановкой задачи мы определились, пора приступать к реализации.

Реализация

Перед реализацией, необходимо провести подготовительную работу, т.е. скопировать компонент bitrix:menu в папку components/ИМЯ_НАШЕГО_NAMESPACE/, так же стоит поменять название, например на left.menu.

Теперь у нас все готово для правки кода. Открываем основной файл компонента component.php и ищем вот такую строчку (в районе 28):

28
$curDir = $APPLICATION->GetCurDir();

Именно этот кусок кода нам и надо отредактировать, функция GetCurDir() – возвращает рабочий каталог, именно эта функция заставляет наш компонент искать файлы меню в отличных от “/” каталогах, после перехода, нам же надо заставить искать файлы всегда, начиная с корня.

Самое простое было бы просто убрать эту функцию и поставить “/”, но тогда данный компонент будет, узкоспециализированным, а нам бы все таки хотелось универсальный инструмент, поэтому мы пойдем немного другим путем. Заменяем данную строку, на такой код:

28
29
30
31
32
33
34
35
/*
Расширение компонента, если параметр $arParams["PATH_MENU"] == "", то меню выводиться
свое для каждого уровня, если имеет параметр /, то всегда полное меню 
*/
if(!$arParams["PATH_MENU"])
	$curDir = $APPLICATION->GetCurDir();
else
	$curDir = $arParams["PATH_MENU"];

После этого добавления, нам нужно поправить файл .parameters.php и внести следующие строчки кода:

1
2
3
4
5
6
"PATH_MENU" => Array(
			"NAME" => "Выводить все уровни, начиная с",
			"TYPE" => "TEXTBOX",
			"DEFAULT" => "",
			"PARENT" => "BASE"
		        ),

Тут особо комментировать нечего, так что воздержусь. Подведем итоги первой части работы: мы выполнили первую часть задания, при этом сохранили стандартный функционал, что, по-моему мнению, является правильным. Теперь для работы нам просто, необходимо поменять компонент и в настройках поставить “/” для нашей опции (параметра).

Вторая часть задания – привязка jQuery меню

Копируем шаблон и начинаем редактировать его, проще сразу все удалить и вставить следующий код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<script src="<?=SITE_TEMPLATE_PATH?>/components/bitrix/menu/LMenu/script.js"></script>
<?
function Img($res, $lvl, $j)
{
	if(isset($res[$j+1]) && ($res[$j+1]["DEPTH_LEVEL"] > $lvl))
	{
		$img = '<img style="padding-top: 6px;" id="plus'.$j.'" name="plus'.$j.'"/>';
	}
	return $img;
}
?>
<?if (!empty($arResult)):?>
	<ul id="menuLeft" class="padding1">		
	<?$realLevel = 1; $idParent = 0;?>
		<?foreach($arResult as $i=>$arItem):?>
			<?if($arItem["DEPTH_LEVEL"] == ($realLevel+1)):?>
				<?$realLevel++;?>
				<ul id="splus<?=$idParent;?>" style="padding-left: 10px; display: none;">
 
			<?endif;?>
			<?if($arItem["DEPTH_LEVEL"] < $realLevel):?>
				<?$realLevel--;?>
				</ul>
			<?endif;?>
			<?if($arItem["DEPTH_LEVEL"] == $realLevel):?>
					<li style="background-image: none;"><?=Img($arResult, $realLevel, $i);?><a href="<?=$arItem["LINK"]?>"><?=$arItem["TEXT"]?></a></li>
			<?endif;?>
			<?
				//устанавливаем нового Папу :-)
				$idParent = $i;
				//echo $idParent."-".$i."<br/>";
			?>
		<?endforeach?>
	</ul>
<?endif?>

Во-второй, строке я сознательно “жестко” подключил файл JS, для наглядности.
Листинг JS файла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$(document).ready(function(){
	$("ul#menuLeft img").each(function() {
		if($.cookie('submenuM-' + this.id)){
			document.images[this.id].src = '/bitrix/templates/binran/images/list-marker1.gif';
			$("ul#s"+this.id).show();
		}else{
			document.images[this.id].src = '/bitrix/templates/binran/images/list-marker.gif';
			$("ul#s"+this.id).hide();
		}
});
 
$(document).ready(function(){
		$("ul#menuLeft img").click(function(){
			if($("ul#s"+this.id).css('display') == 'none')
			{
				cookieSet(this.id);
				$("ul#s"+this.id).slideDown(200);
				document.images[this.id].src = '/bitrix/templates/binran/images/list-marker1.gif';
				$("ul#s"+this.id).css('display') = '';
			}else{
				cookieDel(this.id);
				$("ul#s"+this.id).slideUp(200);
				document.images[this.id].src = '/bitrix/templates/binran/images/list-marker.gif';
			}
		});
	});
});
 
function cookieSet(index) {
	$.cookie('submenuM-' + index, 'opened', {expires: null, path: '/'}); // Set mark to cookie (submenu is shown):
}
function cookieDel(index) {
	$.cookie('submenuM-' + index, null, {expires: null, path: '/'}); // Delete mark from cookie (submenu is hidden):
}

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

Все. Вроде все задания выполнены, есть результат и что самое важное все работает как часы ;)

Подписывайтесь на RSS и Twitter, чтобы не пропустить интересные посты!

С уважением, Главный Лаборант.

Советуем почитать:



7 комментариев к записи “Усовершенствованный компонент 1С-Битрикс bitrix:menu”

  1. Алексей Валеев, написал:

    Если решать именно Вашу задачу (меню от корня всегда), то можно сделать так:
    1. в корне переименовываем .left.menu.php в .lefttop.menu.php
    2. подключаем компонент menu vertical-multilevel с параметрами – меню первого уровня lefttop, остальных уровней left, вложенность – какое-нибудь большое число
    3. все тоже самое что и в статье, начиная со 2го задания.
    Собственно плюс один – заюзанный компонент дефолтный и не теряет обновления

    [Ответить на комментарий]

    Главный Лаборант ответил на комментарий:

    Да это выход – не знал, но что делать с тем, что меню должно показывать уровень вложенности, т.е. можно в пункт меню “Институт” включить подпункты, такой подход как Вы описали подойдет? И еще вопрос в каких редакциях есть такой компонент? Просто я его что то не видел :( Или не заметил, я делал на редакции Старт.

    [Ответить на комментарий]


  2. Алексей Валеев, написал:

    Компонент bitrix:menu, в его настройках Шаблон->vertical_multilevel (в старте есть)
    С вложенностью проблем не возникнет, меню будет строиться с произвольным уровнем глубины. В результате получится тот же массив что и использовался в шаблоне (с arItem["DEPTH_LEVEL"])
    Хотя есть вариант что я неправильно понял задачу :)

    [Ответить на комментарий]

    Главный Лаборант ответил на комментарий:

    А да есть такой шаблон, но скорее всего Вы чуть чуть не до конца поняли задачу, задача заключается в том что на главной (index.php) мы должны показать все меню с вложениями (например, /institut/, а в данной папке второй уровень и так далее) и при переходе на данную страницу (опять таки, как пример /institut/), мы должны показать меню начиная с главной.

    В общем вот так вот.

    [Ответить на комментарий]

    Алексей Валеев ответил на комментарий:

    Видимо задачу я понял все-таки правильно:)
    Попробую объяснить идею подробно:
    1. в корне сайта переименовываем .left.menu.php в .lefttop.menu.php – это надо для того, чтобы в самом верхнем уровне структуры тип меню отличался
    2. подключаем стандартный компонент menu с параметрами как в первом комментарии
    3. принцип действия – в каком уровне вложенности бы мы не находились, битрикс строит меню от корня, потому что .lefttop.menu.php есть только там

    [Ответить на комментарий]

    Главный Лаборант ответил на комментарий:

    Хммм….посмотрел, да Вы правы!
    Очень хороший способ ;)
    Спасибо, учту на будущее, сейчас переделывать уже не буду, так как работа сдана и то задание принято.
    Еще раз спасибо!


  3. Алексей Валеев, написал:

    Кстати, с vertical_multilevel я загнул, этот шаг не нужен)) Вы же все равно полностью заменяете содержимое template.php в шаблоне, так что какой именно кастомизировать не важно)

    [Ответить на комментарий]


Оставить свой комментарий

XHTML: Вы можете использовать следующие теги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">