Создание встроенного модуля CMS. Часть 2
Внимание! Данная статья предполагает, что вы уже читали первую часть.
На этот раз сделаем карту сайта на основе главного меню.
Этот пример скорее учебный, в реальной жизни имеет смысл, если главне меню у вас иерархическое и очень развесистое настолько, что охватить его вниманием, просто гуляя по нему наведением мыши, — дело непростое.
Название
Пусть компонент называется "Карта сайта" для людей, а внутреннее имя будет "sitemap".
Регистрация в базе
INSERT INTO MODULES (MODULENAME, VISIBLE_NAME, M_DEF_LINK, ACCESS, M_PLACE, SHOW_ON) VALUES ('sitemap', 'Карта сайта', 'mod=sitemap', ',6,,2,,4,', 'center', ',AllPage,');
Код модуля
sub sitemap() { # Здесь будет всё самое интересное }
Как хранится главное меню
Раз мы определились, что навигация — это источник данных для карты сайта, первым делом опишу поля таблицы mainmenu из базы CMS.gdb
Таблица mainmenu хранит пункты меню. Одна строка — один пункт.
Описание полей:
(лучше прямо сейчас открывайте таблицу в вашем любимом инструменте и смотрите на то, что CMS положила в таблицу, чтобы представить меню на вашем сайте)
I_ID Идентификатор элемента меню, автоинкрементный счётчик, пользователю не показывается I_NAME Название пункта меню, именно его видит пользователь в редакторе и на сайте I_LINK URL (если в этом поле пусто, значит это папка) I_PARENT Идентификатор папки. Если данный элемент лежит в папке, там будет какое-то число, иначе 0. Пользователю нигде явно не показывается, но иерархия в редакторе и на сайте строится исходя из этого поля. У плоского меню (совсем без иерархии) все значения равны 0. I_LEVEL Уровень вложенности (вложенность не ограничена, допустимо любое число). Минимум 1 — в корне, 2 и выше — в папке. Пользователю нигде не показывается. I_SORT Порядок сортировки. Пользователь перетаскивает элементы мышкой в редакторе, а это поле заполняется соответствующим образом авотматически. Там чиста для самой обычной численной сортировки. PUBLISHED Если там 1, значит пункт меню опубликован, на сайте показывать можно, если там 0 — CMS не должна его показывать на сайте. Поставленная или снятая галочка в редакторе означает 1 или 0 соответственно. OWNER Владелец пункта меню. Если 6, значит школьный сайт. Всё остальное — блоги.
Самый простейший способ показать меню, это сгенерировать список ссылок,
причём, иерархию можно показать исходя из значения I_LEVEL,
и не писать полноценный обход дерева. Этого достаточно для простого списка, который не раскрывается, не подгружается по кликам на узлах, а просто выводится весь сразу.
Для получения минимальных данных, достаточных для такой карты сайта, хватит запроса:
SELECT i_level, i_link, i_name FROM mainmenu WHERE published = 1 AND owner = 6 ORDER BY i_sort
Получается примерно вот такой результат с тремя колонками:
В первой числа (уровень вложенности), во второй — URL, в третьей — название пункта меню. Результат содержит опубликованные пункты меню школьного сайта согласно сортировке.
Теперь из этого добра осталось сгенерировать html-вёрстку (подставляя значения полей каждой строки результата прямо во фрагмент html-кода) и возвратить её из процедуры.
Код
Пишу процедуру, которая покажет плоскуя карту. Зато это уже работающий прототип, пока очень простой и предельно прямой.
sub sitemap() { my $html = '<ul>'; # открываю список # делаю запрос к базе (до q я сократил слово Query, запрос то есть) my $q = sqlpcms('select i_level, i_link, i_name from mainmenu where published = 1 and owner = 6 order by i_sort'); # эта страшная конструкция делает простое удобство: # строки выборки представляются как ключи хеша %hash # это классический рецепт использования DBI, если сложно копируйте, не думая my %hash; $q->bind_columns( \( @hash{ @{$q->{NAME_lc} } } )); # вынимаю результат по одной строчке while ( $q->fetch ) { # дописываю в html-код очередной пункт меню в виде ссылки внутри списка $html .= qq[<li><a href="$hash{i_level}">$hash{i_name}</a></li>]; } $html .= '</ul>'; # закрываю список return $html; # возвращаю полученную html-вёрстку }
Продолжение следует...