Приветствую всех читателей моего блога. Давайте напишем с вами еще один небольшой модуль + укрепим уже пройденный ранее материал по созданию меню для нашего движка. Самая популярная статья в моем блоге - drag and drop nestable menu - без преувеличения, получилась изумительной. Многие комментарии к сожалению удалились при ре дизайне моего сайта и подключения нового движка, но сегодняшний урок будет содержать тоже пару полезных функций.
А результат будет следующий:
- Создадим 2 таблицы в бд - для хранения информации о меню и самих данных
- Напишем рекурсивную функцию для вывода многоуровневого меню
- Напишем функцию для вывода простого(универсального) меню
- Вызовем 2 меню в разных местах сайта с помощью модульного расширения
- Напишем небольшую jquery функцию добавляющую класс 'active' к нужному меню
Модуль menu. Создание базы данных
Итак создадим две таблицы в бд и наполним их верхним(нестандартным) и правым(многоуровневым) меню:
-- -- Структура таблицы `menus` -- CREATE TABLE IF NOT EXISTS `menus` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `menu_name` varchar(50) NOT NULL, `description` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; -- -- Дамп данных таблицы `menus` -- INSERT INTO `menus` (`id`, `name`, `menu_name`, `description`) VALUES (1, 'Главное меню', 'main_menu', 'Главное меню в шапке'), (2, 'Боковое меню', 'right_menu', 'Боковое меню с разделами сайта'); -- -------------------------------------------------------- -- -- Структура таблицы `menus_data` -- CREATE TABLE IF NOT EXISTS `menus_data` ( `id` int(11) NOT NULL AUTO_INCREMENT, `menu_id` int(11) NOT NULL, `name` varchar(64) NOT NULL, `parent_id` varchar(10) DEFAULT NULL, `url` varchar(255) DEFAULT NULL, `order` int(10) DEFAULT NULL, `visible` tinyint(4) DEFAULT NULL, `menu_type` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ; -- -- Дамп данных таблицы `menus_data` -- INSERT INTO `menus_data` (`id`, `menu_id`, `name`, `parent_id`, `url`, `order`, `visible`, `menu_type`) VALUES (1, 1, 'Главная', '0', '/', 0, 1, 'url'), (2, 1, 'Статьи', '0', '/category/articles', 0, 1, 'category'), (3, 1, 'Блог', '0', 'http://polyakov.co.ua', 0, 1, 'url'), (4, 2, 'Главная', '0', '/', 0, 1, 'url'), (5, 2, 'Статьи', '0', '/category/articles', 0, 1, 'category'), (6, 2, 'Первый раздел', '5', '/category/first', 0, 1, 'category'), (7, 2, 'Второй раздел', '5', '/category/second', 0, 1, 'category'), (8, 2, 'Третий раздел', '5', '/category/third', 0, 1, 'category');
Структура модуля menu. Рекурсивная функция вывода многоуровневого меню CodeIgniter 3 + HMVC.
Не будем изменять нашей традиции и создадим папку menu в каталоге modules, контроллер Menu.php и модель Menu_model.php
Теперь для нашего класса Menu мы напишем 2 метода: get_menu(имя_меню) - основная функция, которую мы будем использовать в каждом нашем проекте. _build_tree - будет сердцем нашего модуля, эта функция позволяет строить дерево меню(иерархию) абсолютно любой вложенности.
Обратите внимание! Для скрытия определенных методов от публичного доступа, нужно просто объявить метод частным или защищенным, или в моем случае - добавляем префикс "_" к имени. Наш метод более недоступен по URL запросу.
Дополнительно - get_simple_menu(имя_меню) - примитивная функция, но порой жизненно необходима.
Зачем?
Иногда нужно использовать покупные шаблоны (к примеру с сайта: http://themeforest.net/). А в современных или адаптивных или просто примитивных меню - уже не отделаешься обычной стилизацией #menu>ul>li>ul>li>ul>li. Вот для этого мы напишем функцию выбирая все ссылки и шаблонизируя меню по собственному вкусу и с уникальными стилями. В нашем шаблоне bootstrap как раз такой случай с верхним меню;-)
Итак, код Menu.php и следом Menu_model.php:
Работу контроллера мы описали, проблем с моделью возникнуть не должно - 2 объединения (joins) в одном запросе. позволяет выбирать данные меню не по уникальному идентификатору а по системному имени меню. Это очень удобно при администрировании и запросе нашего модуля из шаблона. Давайте прямо сейчас и сделаем вызов из 3х шаблонов.
Первое - это главное меню в шаблоне index.tpl
В шаблонах category_full.tpl и page_full.tpl мы вызовем правое меню(right_menu) в сайдбаре
На мой взгляд - такая система вывода меню - просто изумительная. Мы можем создавать любое количество навигационных блоков, для любой части сайта. Мы не зависим более от общих библиотек или контроллеров. Мы можем вообще не использовать меню на сайте , если в нем нет нужды.
Давным давно - генерируя меню для сайта - приходилось делать несколько лишних запросов к БД. проверять текущий URL и в цикле производить проверку на совпадение ссылки меню и активной странице - и только тогда добавлять класс 'active'. Сейчас мы возложим эту задачу не на сторону сервера а на сторону клиента - миниатюрным jQuery скриптом, функционирующем при готовности страницы.
Не забудьте добавить стили для каждого из меню, что бы увидеть скрипт в действии. Класс 'active' верхнего меню остался с исходников шаблона bootstrap, напомню:
Вот и все на сегодня. Надеюсь, вы под черпнули из данного урока пару трюков для будущей работы с 3й версией фреймворка.
Как всегда полные исходные коды движка на Codeigniter 3 + HMVC со всеми последними модулями.
P.S. Судя по обильным комментариям за последнюю неделю - всем очень нравится серия статей по CI! Я очень этому рад и горжусь что мы с вами уже набрали обороты в разработке не похожего ни на один другой на мой взгляд движка.
При запуске исходных кодов на рабочем хостинге, пользователь NEPALEX - выявил баг из за которой выводилась 404 ошибка. Огромная ему за это благодарность. Теперь на домен http://ci3.polyakov.co.ua я буду выкладывать последнюю версию движка (с новыми модулями, разбираемыми в статьях).
А пока, жду ваши комментарии и легкого вам программирования.
Павел
Спасибо.. Параллельно тоже буду повторять примеры на хостинге..