Вход / Регистрация


Вход на сайт:
Логин: 
Пароль: 


Впервые здесь?
 
Регистрация [?]:
Регистрация у нас позволит:
  • Покупать платные продукты из каталога и иметь к ним доступ в любое время
  • Задавать вопросы другим людям, участвовать в дискуссиях
  • Публиковать свои расширения, программы и софт, если Вы разработчик или дистрибьютор
  • Добавлять интересные ссылки и иметь к ним доступ из любой точки, где есть выход в Интернет
  • Следить за обновлениями сервиса и получать дополнительные возможности, которых не имеют обычные гости
  • Следить за новыми статьями и получать новые знания
Выберите логин:
Ваш Email:
Введите результат выполнения операции (цифрами):
15 - 2 = ? Обновить

Адаптируем стороннее меню под Joomla. Делаем свой модуль меню для Joomla 2.5 (Часть 1) PDF Печать E-mail
Автор: Максим   
15.08.2013 22:10
Понравилось:
30


Не понравилось: 4
Недоступен ни один перевод.

Доброго времени суток, друзья. По результатам нашего опроса на сайте "Какая статья следующая?" наибольшую популярность получили две темы - это написание своего компонента под Joomla 2.5 и адаптация стороннего выпадающего меню и превращение его в модуль для Joomla. Спасибо, кстати, всем голосовавшим - если Вы ждали данную статью, то хочется верить, что дождались. Ввиду обширности темы написания компонентов под Joomla 2.5 я взял её на заметку и буду прорабатывать. А пока посмотрим на то, как адаптировать стороннее меню и сделать из него полноценный модуль меню для Вашего сайта Joomla 2.5.

Существующие сторонние меню и выбор одного из них

Начну с небольшой заметки: на сегодняшний день уже существует довольно большое количество разнообразных меню под разные версии Joomla. Но у каждого из них есть свой нюанс, и подчас они "криво" устанавливаются на сайт или совсем не подходят под нужный шаблон. Что-то поползло, что-то поехало, ну... Вы и так прекрасно понимаете, о чем я... Так вот, когда очень нужен модуль меню - правильно работающий и не конфликтующий с нужным шаблоном - остается два пути: покупать готовый модуль или написать его самому. 
 
Первый возникающий вопрос - с чего начать? А начинать нужно с понимания, что мы хотим получить в итоге. Нужно ли нам навороченное динамическое меню с красивыми эффектами "выплывания" или скольжения, но которое нужно очень аккуратно адаптировать под все современные браузеры? Чтобы не дай Бог где-нибудь оно отображалось или "выплывало" не так, как нужно. Или же взять простое выпадающее меню без эффектов и наворотов, но с гарантией правильной работы в любом браузере. Не знаю как Вы, а я ценю практичность и простоту. Поэтому выбираю второй вариант. Но независимо от того, по какому пути идти, - необходимо выбрать то самое стороннее меню, из которого будем выпиливать наш модуль для Joomla.
 
Как и где найти эти меню? Всё очень просто, любой поисковик предложит вам десятки, а то и сотни вариантов самых разнообразных выпадающих меню. Лично я предпочитаю делать поиск на англоязычных сайтах. Там различных меню гораздо больше, чем в рунете. Вот, к примеру, первая стоящая ссылка, которую я нахожу через поиск:
 
 
Если Вы перейдете по ссылке и ознакомитесь с примерами бесплатных меню и уроками по их созданию и вставке на Ваш сайт, то опять увидите - из всех этих примеров меню есть навороченные, а есть попроще. Я остановился на следующем варианте - 27. Simple jQuery Dropdowns, который Вы увидите, перейдя по ссылке. Результат его переработки под модуль Joomla Вы в данный момент видите на нашем сайте. Именно его я взял за основу для адаптации под Joomla и на нём покажу технику написания модуля меню. Выбрал его по двум основным причинам:
 
1. Автор и производитель этого меню известнейший и авторитетный западный сайт о Веб-дизайне и CSS-трюках - http://css-tricks.com. А значит, ошибки, связанные с работой в разных браузерах исключены. И качество кода меню будет на высоте. А вот и страница этого самого меню, если Вы её еще не нашли: http://css-tricks.com/simple-jquery-dropdowns/
 
2. Меню очень простое, но крайне функциональное. Вот что пишут на странице сами авторы:
  • Кросс-браузерная совместимость (даже IE6)
  • Многоуровневое
  • Минимальная стилизация (легко в адаптации)
  • Минимальный JavaScript (маленький кусочек jQuery)
Что еще нужно для хорошего меню? ;)

Определяем шаги, необходимые для адаптации меню под Joomla и превращения его в модуль

Итак, мы определились с выбором стороннего меню, нашли приемлемый вариант и скачали. Дальше, конечно, можно начать изучать код, который заставляет выбранное меню работать. В большинстве (если не во всех) примерах меню, которые скачиваются, демонстрация меню представляет из себя следующие файлы:
  • один или несколько файлов CSS-стилей, оформляющих меню и различные ресурсы (картинки, спрайты и т.д.)
  • index.html / demo.html или другая страничка с примером разметки и демонстрационными пунктами меню
  • скрипты JavaScript / jQuery, добавляющие динамику в меню. Это эффекты (выплывание, скольжение и т.д.) или сама реализация логики "выпадания"
Скажу сразу - адаптировать можно абсолютно любое по сложности стороннее меню и сделать из него модуль Joomla. Всё зависит от знаний и навыков, а главное - умении читать и понимать чужой код. Но Вы облегчите себе задачу и сэкономите нервы, если подберете что-нибудь попроще (как наш рассматриваемый пример).
  
Далее, когда мы разобрались с тем, что из себя представляет демо-пример стороннего меню, мы должны сделать следующие вещи:
 
1. Написать пустой модуль-"заглушку" для Joomla и установить его на наш сайт Joomla. Включить его через админ-панель и установить в нужную позицию шаблона.
2. Прямо в установленный на сайт модуль-заглушку последовательно вставлять куски кода из скачанного нами примера. Т.е. методом "Копировать-Вставить" делаем перенос CSS-стилей, разметки, картинок и прочего. Если CSS-стили можно вставлять сначала прямо без изменений, то html-код потребуется значительно видоизменить, поскольку мы хотим вместо статичных демо-пунктов меню получить реальные пункты внутреннего меню Joomla.
3. "Доводить" код в нашей заглушке до состояния готовности, т.е. когда внешний вид меню и его правильная работа с ядром Joomla не станут приемлимыми для нас. Это часть самая сложная, поскольку тут вступают в силу такие нюансы, как корректная работа меню под максимальное количество шаблонов и знание внутреннего устройства меню Joomla. Хотя, если Вы не делаете коммерческий модуль, об этом можно не заботиться - главное, чтобы меню работало правильно хотя бы в Вашем конкретном шаблоне. Таким образом, на этом шаге наша пустая "заглушка"-модуль постепенно превратится в полностью рабочий модуль меню.
4. Когда модуль готов, вырезать его в отдельную папку, заархивировать и превратить в полноценный дистрибутив модуля меню Joomla.
 
Пожалуй, я не смогу в этой статье охватить все нюансы "доводки" модуля, поскольку в каждом конкретном случае она абсолютно различна и требует изобретательности, навыков, творческой составляющей, "видения" как модуль должен работать, ну и, конечно, большого желания сделать свой модуль меню. Однако я объясню читателю следующие вещи:
 
1. Как взять пустую заглушку-модуль, и сделать из неё модуль меню
2. На что обратить внимание при доработке заглушки
3. Как устроена внутренняя реализация меню Joomla. Мы напишем свой класс-помощник, который позволит удобно работать с меню.
 
Итак, поехали.

Установка модуля-заглушки для будущего меню

Заглушку (будущий модуль меню) назовём mod_colormenu. Внутреняя структура модуля-заглушки будет стандартна для большинства модулей, и будет состоять из следующих файлов и каталогов:
  • /mod_colormenu/mod_colormenu.xml - дескриптор модуля
  • /mod_colormenu/mod_colormenu.php - точка входа модуля с минимумом функционала, т.е. пока без логики
  • /mod_colormenu/index.html - пустой индексный файл
  • /mod_colormenu/helper.php - заготовка для класса-помощника. Класс-помощник возьмет на себя самые основные задачи - по формированию массива элементов меню, полученного из ядра Joomla и обработке этого массива
  • /mod_colormenu/tmpl/default.php - файл "вывода" модуля. здесь будет html-разметка нашего меню в сочетании с php-кодом по перебору пунктов меню Joomla.
  • /mod_colormenu/tmpl/index.html - пустой индексный файл
  • /mod_colormenu/css/mod_colormenu.css - файл стилей
  • /mod_colormenu/js/mod_colormenu.js - файл JavaScript для модуля
  • /mod_colormenu/js/index.html пустой индексный файл

Наша заглушка - это по сути простейший, "пустой" модуль-каркас для Joomla 2.5, и я не возьмусь объяснять, как его написать для экономии времени и места.

Если Вы еще не знакомы с написанием модулей под Joomla 2.5, то найти подобную информацию о том, как написать Ваш первый модуль "HelloWorld" с нуля, можно тут.

Скачать нашу заглушку-модуль можно здесь.

Устанавливаем её на сайт (желательно локальный), где будет вестись разработка модуля меню, т.к. нам понадобится иметь полный доступ к файлам установленной заглушки. В нашем примере я выбрал стандартный шаблон Joomla Beez_20 для front-end части и установил модуль в позицию position-1:

alt

 

А так наш модуль-заглушка выглядит на самом сайте. Как видите, пока он просто выводит строку текста "Это заглушка для модуля меню":

alt

 

Наполнение заглушки

После того, как мы установили заглушку на сайт, начинаем потихоньку превращать её в полноценный модуль. Чтобы избежать многократных установок, я предпочитаю все правки делать прямо в том месте, куда Joomla установила модуль. После того, как всё работает должным образом, я упаковываю файлы модуля в архив и делаю полноценный дистрибутив. Мы поступим так же. Итак, переходим в корень сайта Joomla, и открываем каталог с файлами нашей заглушки /modules/mod_colormenu/. Первое, что мы будем делать - это наполним логикой файл helper.php. Создадим следующий классMenuItemдля хранения элемента меню:


class MenuItem { 
Недоступен ни один перевод.

Доброго времени суток, друзья. По результатам нашего опроса на сайте "Какая статья следующая?" наибольшую популярность получили две темы - это написание своего компонента под Joomla 2.5 и адаптация стороннего выпадающего меню и превращение его в модуль для Joomla. Спасибо, кстати, всем голосовавшим - если Вы ждали данную статью, то хочется верить, что дождались. Ввиду обширности темы написания компонентов под Joomla 2.5 я взял её на заметку и буду прорабатывать. А пока посмотрим на то, как адаптировать стороннее меню и сделать из него полноценный модуль меню для Вашего сайта Joomla 2.5.

Существующие сторонние меню и выбор одного из них

Начну с небольшой заметки: на сегодняшний день уже существует довольно большое количество разнообразных меню под разные версии Joomla. Но у каждого из них есть свой нюанс, и подчас они "криво" устанавливаются на сайт или совсем не подходят под нужный шаблон. Что-то поползло, что-то поехало, ну... Вы и так прекрасно понимаете, о чем я... Так вот, когда очень нужен модуль меню - правильно работающий и не конфликтующий с нужным шаблоном - остается два пути: покупать готовый модуль или написать его самому. 
 
Первый возникающий вопрос - с чего начать? А начинать нужно с понимания, что мы хотим получить в итоге. Нужно ли нам навороченное динамическое меню с красивыми эффектами "выплывания" или скольжения, но которое нужно очень аккуратно адаптировать под все современные браузеры? Чтобы не дай Бог где-нибудь оно отображалось или "выплывало" не так, как нужно. Или же взять простое выпадающее меню без эффектов и наворотов, но с гарантией правильной работы в любом браузере. Не знаю как Вы, а я ценю практичность и простоту. Поэтому выбираю второй вариант. Но независимо от того, по какому пути идти, - необходимо выбрать то самое стороннее меню, из которого будем выпиливать наш модуль для Joomla.
 
Как и где найти эти меню? Всё очень просто, любой поисковик предложит вам десятки, а то и сотни вариантов самых разнообразных выпадающих меню. Лично я предпочитаю делать поиск на англоязычных сайтах. Там различных меню гораздо больше, чем в рунете. Вот, к примеру, первая стоящая ссылка, которую я нахожу через поиск:
 
 
Если Вы перейдете по ссылке и ознакомитесь с примерами бесплатных меню и уроками по их созданию и вставке на Ваш сайт, то опять увидите - из всех этих примеров меню есть навороченные, а есть попроще. Я остановился на следующем варианте - 27. Simple jQuery Dropdowns, который Вы увидите, перейдя по ссылке. Результат его переработки под модуль Joomla Вы в данный момент видите на нашем сайте. Именно его я взял за основу для адаптации под Joomla и на нём покажу технику написания модуля меню. Выбрал его по двум основным причинам:
 
1. Автор и производитель этого меню известнейший и авторитетный западный сайт о Веб-дизайне и CSS-трюках - http://css-tricks.com. А значит, ошибки, связанные с работой в разных браузерах исключены. И качество кода меню будет на высоте. А вот и страница этого самого меню, если Вы её еще не нашли: http://css-tricks.com/simple-jquery-dropdowns/
 
2. Меню очень простое, но крайне функциональное. Вот что пишут на странице сами авторы:
  • Кросс-браузерная совместимость (даже IE6)
  • Многоуровневое
  • Минимальная стилизация (легко в адаптации)
  • Минимальный JavaScript (маленький кусочек jQuery)
Что еще нужно для хорошего меню? ;)

Определяем шаги, необходимые для адаптации меню под Joomla и превращения его в модуль

Итак, мы определились с выбором стороннего меню, нашли приемлемый вариант и скачали. Дальше, конечно, можно начать изучать код, который заставляет выбранное меню работать. В большинстве (если не во всех) примерах меню, которые скачиваются, демонстрация меню представляет из себя следующие файлы:
  • один или несколько файлов CSS-стилей, оформляющих меню и различные ресурсы (картинки, спрайты и т.д.)
  • index.html / demo.html или другая страничка с примером разметки и демонстрационными пунктами меню
  • скрипты JavaScript / jQuery, добавляющие динамику в меню. Это эффекты (выплывание, скольжение и т.д.) или сама реализация логики "выпадания"
Скажу сразу - адаптировать можно абсолютно любое по сложности стороннее меню и сделать из него модуль Joomla. Всё зависит от знаний и навыков, а главное - умении читать и понимать чужой код. Но Вы облегчите себе задачу и сэкономите нервы, если подберете что-нибудь попроще (как наш рассматриваемый пример).
  
Далее, когда мы разобрались с тем, что из себя представляет демо-пример стороннего меню, мы должны сделать следующие вещи:
 
1. Написать пустой модуль-"заглушку" для Joomla и установить его на наш сайт Joomla. Включить его через админ-панель и установить в нужную позицию шаблона.
2. Прямо в установленный на сайт модуль-заглушку последовательно вставлять куски кода из скачанного нами примера. Т.е. методом "Копировать-Вставить" делаем перенос CSS-стилей, разметки, картинок и прочего. Если CSS-стили можно вставлять сначала прямо без изменений, то html-код потребуется значительно видоизменить, поскольку мы хотим вместо статичных демо-пунктов меню получить реальные пункты внутреннего меню Joomla.
3. "Доводить" код в нашей заглушке до состояния готовности, т.е. когда внешний вид меню и его правильная работа с ядром Joomla не станут приемлимыми для нас. Это часть самая сложная, поскольку тут вступают в силу такие нюансы, как корректная работа меню под максимальное количество шаблонов и знание внутреннего устройства меню Joomla. Хотя, если Вы не делаете коммерческий модуль, об этом можно не заботиться - главное, чтобы меню работало правильно хотя бы в Вашем конкретном шаблоне. Таким образом, на этом шаге наша пустая "заглушка"-модуль постепенно превратится в полностью рабочий модуль меню.
4. Когда модуль готов, вырезать его в отдельную папку, заархивировать и превратить в полноценный дистрибутив модуля меню Joomla.
 
Пожалуй, я не смогу в этой статье охватить все нюансы "доводки" модуля, поскольку в каждом конкретном случае она абсолютно различна и требует изобретательности, навыков, творческой составляющей, "видения" как модуль должен работать, ну и, конечно, большого желания сделать свой модуль меню. Однако я объясню читателю следующие вещи:
 
1. Как взять пустую заглушку-модуль, и сделать из неё модуль меню
2. На что обратить внимание при доработке заглушки
3. Как устроена внутренняя реализация меню Joomla. Мы напишем свой класс-помощник, который позволит удобно работать с меню.
 
Итак, поехали.

Установка модуля-заглушки для будущего меню

Заглушку (будущий модуль меню) назовём mod_colormenu. Внутреняя структура модуля-заглушки будет стандартна для большинства модулей, и будет состоять из следующих файлов и каталогов:
  • /mod_colormenu/mod_colormenu.xml - дескриптор модуля
  • /mod_colormenu/mod_colormenu.php - точка входа модуля с минимумом функционала, т.е. пока без логики
  • /mod_colormenu/index.html - пустой индексный файл
  • /mod_colormenu/helper.php - заготовка для класса-помощника. Класс-помощник возьмет на себя самые основные задачи - по формированию массива элементов меню, полученного из ядра Joomla и обработке этого массива
  • /mod_colormenu/tmpl/default.php - файл "вывода" модуля. здесь будет html-разметка нашего меню в сочетании с php-кодом по перебору пунктов меню Joomla.
  • /mod_colormenu/tmpl/index.html - пустой индексный файл
  • /mod_colormenu/css/mod_colormenu.css - файл стилей
  • /mod_colormenu/js/mod_colormenu.js - файл JavaScript для модуля
  • /mod_colormenu/js/index.html пустой индексный файл

Наша заглушка - это по сути простейший, "пустой" модуль-каркас для Joomla 2.5, и я не возьмусь объяснять, как его написать для экономии времени и места.

Если Вы еще не знакомы с написанием модулей под Joomla 2.5, то найти подобную информацию о том, как написать Ваш первый модуль "HelloWorld" с нуля, можно тут.

Скачать нашу заглушку-модуль можно здесь.

Устанавливаем её на сайт (желательно локальный), где будет вестись разработка модуля меню, т.к. нам понадобится иметь полный доступ к файлам установленной заглушки. В нашем примере я выбрал стандартный шаблон Joomla Beez_20 для front-end части и установил модуль в позицию position-1:

alt

 

А так наш модуль-заглушка выглядит на самом сайте. Как видите, пока он просто выводит строку текста "Это заглушка для модуля меню":

alt

 

Наполнение заглушки

После того, как мы установили заглушку на сайт, начинаем потихоньку превращать её в полноценный модуль. Чтобы избежать многократных установок, я предпочитаю все правки делать прямо в том месте, куда Joomla установила модуль. После того, как всё работает должным образом, я упаковываю файлы модуля в архив и делаю полноценный дистрибутив. Мы поступим так же. Итак, переходим в корень сайта Joomla, и открываем каталог с файлами нашей заглушки /modules/mod_colormenu/. Первое, что мы будем делать - это наполним логикой файл helper.php. Создадим следующий классMenuItemдля хранения элемента меню:


class MenuItem {
	// копии стандартных Joomla-атрибутов для пункта меню
	private $id;
	private $parent_id;
	private $type;
	private $menutype;
	private $access;
	private $user;
	// Собственные атрибуты
	private $children; // Массив дочерних пунктов меню. каждый элемент - тоже экземпляр нашего класса MenuItem
	private $itemText; // Текст пункта меню. Используется для отрисовки пункта меню на сайте
	private $startTag; // Открывающий тег. Используется для отрисовки пункта меню
	private $endTag; // Закрывающий тег. Используется для отрисовки пункта меню
	private $enableDropSymbol; // Признак - разрешить картинку стрелки для пункта меню
	private $dropSymbol; // Спец-символ стрелки для пункта меню. Будет отображается для тех пунктов, у которых есть дочерние элементы (2-й уровень меню)

	const ACCESS_ALL = 1;
	const ACCESS_REGISTERED = 2;
	const ACCESS_SPECIAL = 3;

	function __construct($item) {
		// при создании экземпляра копируем родные атрибуты Joomla
		$this->id = $item->id;
		$this->type = $item->type;
		$this->menutype = $item->menutype;
		$this->parent_id = $item->parent_id;
		$this->access = $item->access;
		// при создании сначала считаем, что дочерних пунктов у этого пункта меню нет
		$children = null;
	}

	function setUser(& $user) { $this->user = $user; }
	function getUser() { return $this->user; }

	function setItemText($text) { $this->itemText = $text; }
	function getItemText() { return $this->itemText; }

	function setStartTag($startTag) { $this->startTag = $startTag; }
	function getStartTag() { return $this->startTag; }

	function setEndTag($endTag) { $this->endTag = $endTag; }
	function getEndTag() { return $this->endTag; }

	function setParent($parent_id) { $this->parent_id = $parent_id; }
	function getParent() { return $this->parent_id; }

	function setId($id) { $this->id = $id; }
	function getId() { return $this->id; }

	function setEnableDropSymbol($enable) { $this->enableDropSymbol = $enable; }
	function getEnableDropSymbol() { return $this->enableDropSymbol; }

	function setDropSymbol($dropSymbol) { $this->dropSymbol = $dropSymbol; }
	function getDropSymbol() { return !empty($this->dropSymbol) ? $this->dropSymbol : ""; }
	function getType() { return $this->type; }

	function setAccess($access) { $this->access = $access; }
	function getAccess() { return $this->access; }

	// Добавить дочерний пункт меню в массив "детей"
	function addChild(MenuItem $item) {
		if (empty($this->children)) $this->children = array();
		array_push($this->children, $item);
	}

	// true, если этот пункт является корневым. У него нет дочерних элементов и для
	// него hasChildren() будет тоже возвращать true
	function isRoot() {
		return $this->parent_id == 1;
	}

	// true если у пункта меню есть дочерние элементы
	function hasChildren() {
		return !empty($this->children) && count($this->children) > 0;
	}

	function hasAccessableChildren() {
		if (empty($this->children) || count($this->children) == 0 || empty($this->user)) return false;
		foreach ($this->children as $child) {
			if ($child->isAccessable($this->user)) return true;
		}
		return false;
	}

	function isAccessable(& $user) {
		if ($user->guest) {
			if ($this->getAccess() == self::ACCESS_ALL) return true;
		} else {
			if ($this->getAccess() >= self::ACCESS_ALL) return true;
		}
		return false;
	}

	// Возвращает строковое представление пункта меню. Главный метод отрисовки пункта меню
	function render() {
		$output = "";
		// ... здесь будет логика для формирования строки с HTML-разметкой пункта меню
		return $output;
	}
}

Копируем кусок кода с определением классаMenuItem, приведенный выше, и вставляем его сразу после первой строки, которая проверяет санкционированность доступа к файлу helper.php:


defined( '_JEXEC' ) or die( 'Restricted access' );

// сюда вставляем код, определеяющий класс MenuItem:
class MenuItem {
// ...
}

Итак, на данном этапе у нас в файле helper.php определены два класса -MenuItemи класс помощника -modColorMenuHelper- он сразу был в файле, но пустой, т.е. без какой-либо логики. Также, можно заметить, что методrender() классаMenuItemпока что пустой. Чуть позже мы напишем код, который будет там использоваться.

Меню Joomla с точки зрения базы данных представлено в версии Joomla 2.5 в двух таблицах (для более ранних версий, например 1.5 это также две таблицы, однако состав полей у них уже другой):

  • prefix_menu - в этой таблице хранятся все элементы меню, причем это касается всех уровней (вложенные элементы для меню 2-го, 3-го и т.д. уровней также хранятся в этой таблице)
  • prefix_menu_types - в этой таблице хранятся типы меню. Например, если в менеджере меню Joomla вы создаете новые меню, то они попадут в эту таблицу

* prefix_ - это 5-ти символьный префикс таблиц в базе данных. Он определяется (генерируется) на этапе первоначальной установки Joomla и отличается для разных баз данных. Например, в моей базе данных таблица называется так: yrepq_menu, у вас она будет называться по-другому.

Чтобы лучше понимать - вот рисунок, где показана структура таблицы prefix_menu:

На заметку: на скриншотах вы можете видеть таблицы базы данных MySQL. Я рекомендую скачать утилиту Navicat Lite для подключения к базе данных MySQL. Она бесплатна и позволяет удобно просматривать все таблицы Joomla. Скачать её можно в нашем каталоге тут

Зачем мы определили классMenuItem?По сути, в объектах данного класса будут храниться записи из таблицы prefix_menu. В Joomla уже есть механизм доступа к меню через системные вызовы. Но на мой взгляд, он не сильно удобен. Именно поэтому для удобного хранения элемента меню и работы с ним мы и написали классMenuItem. Чтобы вы лучше ориентировались и понимали, что собой представляет данный класс, я приведу описание его полей:

  • id- будет хранить значение из столбца id для конкретного пункта меню из таблицы prefix_menu. Это уникальный идентификатор пункта меню и первичный ключ таблицы prefix_menu.
  • parent_id- будет хранить значение из столбца parent_id для конкретного пункта меню из таблицы prefix_menu. Т.е. в данном поле будет храниться id "родительского" пункта меню. Если пункт меню сам является "родительским", т.е. находится на первом уровне вложенности, значением его parent_id будет 1 - в Joomla есть всегда специальный элемент "Menu_Item_Root" с id равным 1. Этот специальный элемент - всегда будет родителем для элементов меню первого уровня.
  • type - будет хранить значение из столбца type для пункта меню из таблицы prefix_menu. Это тип пункта меню. Например, для пунктов меню, привязанных к компонентам в столбце type таблицы prefix_menu будет храниться значение "component"
  • menutype- будет хранить значение из столбца menutype таблицы prefix_menu. В этом поле будем хранить название типа меню, с которым связан пункт меню. Например, для пункта меню  из "Главного меню" в этом поле будет значение "mainmenu". Это же поле есть во второй таблице, которую я уже упоминал - prefix_menu_type. Значения поля в обеих таблицах одинаковые.
  • access- будет хранить значение из столбца access таблицы prefix_menu. В этом поле Joomla хранит числовое значение, которое определяет видимость пункта меню для разных типов пользователей: 1 - пункт видим всем пользователям (даже гостям), 2 - видим только зарегистрированным пользователям, 3 - специальный доступ. 0 означает, что пункт меню снят с публикации в панели администрирования Joomla и невидим ни для кого.
  • user- ссылка на текущего пользователя Joomla. Через эту ссылку в классе мы всегда сможем получать доступ к текущему пользователю Joomla, и соответственно узнавать его параметры - гость он или зарегистрированный (и т.д.)
  • children- массив "детей" данного пункта меню, т.е. дочерних пунктов меню. Визуально в панели администрирования Joomla, когда Вы редактируете стандартное меню, эти пункты отображаются с отступом, под родительским пунктом меню.
  • itemText- текст текущего пункта меню, т.е. это текст, что используется для отрисовки пункта на сайте.
  • startTag- открывающий тег. Используется для отрисовки пункта меню. Суть этой переменной такова - могут быть разные типы пунктов меню - URL, разделитель и т.д. Так вот - в зависимости от типа меню у нашего пункта меню может быть разная HTML-разметка. startTag - это не что иное, как открывающий HTML-тег, нужный для отрисовки пункта. Это может быть <span>, <a> или любой другой тег, внутрь которого будет помещено значение текста пункта меню, т.е.itemText
  • endTag- закрывающий тег. Аналогично переменной классаstartTagможет содержать значение для закрывающего HTML-тега меню (</span>, </a> и т.д.)
  • enableDropSymbol- булева переменная (true/false), которая определяет, будет ли отображаться спецсимвол рядом с пунктом меню или нет. В данной реализации класса я решил ограничиться ASCII-символом, вместо того, чтобы использовать графику для отображения того пункта меню, у которого будут дочерние элементы. 
  • dropSymbol- непосредственно значение спецсимвола, который отображается у "родительских" пунктов меню (при наведении на них будет всплывать подменю). Это переменная-строка, желательно содержащая единственный символ, например ">"

Пишем запрос, объединяющий таблицы menu и menu_types

Теперь, когда мы рассмотрели назначение полей класса я объясню, как написать SQL-запрос в базу данных Joomla, который позволит объединить две таблицы: menu и menu_types. Зачем объединять эти таблицы? А для того, чтобы сопоставить каждый пункт меню с тем типом меню, для которого он задан. Давайте взглянем на рисунок, чтобы лучше понимать, как объединяются таблицы по полю menutype:

Как видим поле menutype общее для обеих таблиц. И оно будет являться связкой между пунктом меню и типом меню, которому он соответствует. Теперь осталось написать такой SQL-запрос и добавить его в функцию в наш класс помощника modColormenuHelper. Функцию назовем getDefMenuParams (от "get default menu params" - получить параметры меню по умолчанию):


public function getDefMenuParams($menutype) {
	$db = &JFactory::getDBO();
	$query = $db->getQuery(true);
 	$query->select("mt.menutype, mt.title as menutitle, mt.description, m.title as itemtitle, m.alias, m.link, m.type, m.published, m.parent_id, m.access");
	$query->from('#__menu as m');
	$query->leftJoin('#__menu_types as mt ON m.menutype = mt.menutype');
	$query->where("mt.menutype = '" . $menutype . "'");
	$query->where("m.published = 1");
	$query->order("m.ordering asc");
	$db->setQuery($query);
	$list = $db->loadObjectList();

	if (!empty($list) && count($list) > 0) {
		return $list[0];
	}

	return null;
}

Как видим, функция принимает входной параметр -$menutype. В него мы будем передавать строку с названием определенного типа меню, информация по которому нас интересует. Например, если передадим в качестве параметра строку "mainmenu", то после выполнения SQL-запроса мы получим объединение двух таблиц, которое вернет нам все опубликованные в админке пункты главного меню, а также название их типа меню - "Главное Меню" (см. рисунок). Также мы задаем сортировку найденных результатов - по полю ordering в возрастающем порядке. Это значит, что пункты меню вернутся нам в массиве результатов в том порядке, в котором они отсортированы в интерфейсе панели администрирования Joomla.

Пишем метод getMenuItems для получения пунктов меню

Напишем в нашем классе хелпера modColormenuHelper такой метод, который назовём getMenuItems:


public function getMenuItems($menutype) {
	// результирующий массив элементов MenuItem. Его вернем на выходе
	$resultItems = array();

	// массив "необработанных детей". Сюда попадут дочерние элементы подменю, так и не добавленные к "родителю"
	// после первого прохода по элементам.
	$unusedChildren = array();

	// Получить меню сайта через Joomla API
	$app = & JFactory::getApplication();
	$menu = $app->getMenu();
	$user = & JFactory::getUser();

	// Получить элементы меню для определенного типа меню
	$items = $menu->getItems("menutype", $menutype);

	// Если вдруг элементов нет, выходим из метода и возвращаем null
	if (empty($items)) return null;

	for ($i = 0, $n = count($items); $i < $n; $i++) {
		$item = $items[$i]; 
		if ($item->menutype != $menutype ) continue;
		$mnuItem = new MenuItem($item);
		$mnuItem->setUser($user);

		// Обработать Jooml-овский пункт меню и дополнить наш $mnuItem недостающими данными
		$this->processJoomlaMenuItem ( $item, $mnuItem );
		// Если текущий пункт меню - родительский, просто добавляем его в массив финальных элементов
		if ($mnuItem->isRoot()) {
			array_push($resultItems, $mnuItem);
		} else {
			// Если текущий пункт меню не родитель, то его нужно добавить в children нужного родителя
			$bFound = false;
			foreach ($resultItems as $rItm) {
				if ($mnuItem->getParent() == $rItm->getId()) {
					$rItm->addChild($mnuItem);
					$bFound = true;
				}
			}
			// Следующее условие _СКОРЕЕ ВСЕГО_ не выполнится, т.к. движок Joomla уже упорядочивает элементы следующим образом - сначала родительские, затем дочерние
			// Но мы оставим на всякий случай эту проверку - она не сильно помешает.
			// Если так и не нашли нужного родителя. Это может быть по причине того, что
			// пытались обработать дочерний элемент ДО ТОГО, как родитель попал в $resultItems
			// Поэтому помещаем дочерний пункт меню в массив "необработанных детей" - unusedChildren
			if (!$bFound) {
				array_push($unusedChildren, $mnuItem);
			}
		}
	} 
	// Если нашлись "необработанные дети" - пробежимся по каждому и "обработаем" - добавим их к нужному родителю,
	// чтобы отрисовалось всё как надо. Опять же, в этот if мы _СКОРЕЕ ВСЕГО_ не войдем, но он для подстраховки
	if (count($unusedChildren) > 0) {
		foreach ($unusedChildren as $child) {
			foreach ($resultItems as $rItm) {
				if ($child->getParent() == $rItm->getId()) {
					$rItm->addChild($mnuItem);
				}
			}
		}
	}
	return $resultItems;
} 

Обратите внимание, что пока нет метода processJoomlaMenuItem() - его мы напишем далее по тексту. Я постарался прокомментировать код, поэтому основные участки уже объяснил. Суть метода такова: получить на вход тип меню, а на выходе вернуть все пункты меню для него в виде массива. Причем на выходе мы возвращаем массив элементов, тип которых - MenuItem, т.е. это тот самый класс, который мы писали и рассматривалии ранее. Напомню, нужен он для того, чтобы было проще работать с пунктом меню. Вы, наверно, заметили по комментарию, что в рассмотренном только что методе getMenuItems() мы сначала получали меню Joomla с помощью вызова Joomla API:


	// Получить меню сайта через Joomla API
	$app = & JFactory::getApplication();
	$menu = $app->getMenu();

После этого вызова мы имеем переменную $menu, и через нее можем получить информацию о пунктах меню:


	$items = $menu->getItems("menutype", $menutype);


Но работать с таким массивом не совсем удобно, т.к. мы не имеем структуры для работы с иерархией меню, т.е. такой структуры, которая бы позволяла удобно хранить информацию об отношениях "родитель-потомок" между пунктами меню. Именно поэтому мы писали свой класс MenuItem - чтобы иметь массив "детей" (переменная класса$children) для каждого типа меню. А в рассмотренном только что методе мы как раз заполняем этот массив детей по следующему простому алгоритму:

1. Есть массив пунктов меню $resultItems, который должны вернуть на выходе из метода

2. Если текущий обрабатываемый пункт меню - уже родитель, то просто добавляем его в массив $resultItems

3. Если текущий обрабатываемый пункт меню - НЕ родитель, то мы бежим по массиву $resultItems и проверяем того родителя, к которому нужно добавить текущий элемент как дочерний

Продолжение статьи - тут

Скачать заглушку для модуля

Скачать готовый модуль



Обновлено 09.11.2013 21:26
 
Автор статьи: Damascus
Всего статей: 62
Рейтинг: 3111
Страница Google+: Google

Нашли ошибку?

Система Orphus

Оплата на сайте

Яндекс.Деньги
www.megastock.ru
Здесь находится аттестат нашего WM идентификатора 207935874510
Проверить аттестат

Статистика сайта

Яндекс.Метрика

Мы в Интернете


Allineed.Ru © 2009-2012 - Allineed.Ru - ответы на IT вопросы, статьи о разработке, IT и программном обеспечении. При использовании материалов сайта ссылка обязательна. Использование данного сайта и любой его части означает принятие условий Пользовательского Соглашения.
Allineed.Ru is not affiliated with or endorsed by the Joomla! Project or Open Source Matters. The Joomla! name and logo is used under a limited license granted by Open Source Matters the trademark holder in the United States and other countries.