Привет всем! Добро пожаловать на Блог RS! Сегодня, как видно из заголовка поста, мы с Вами реализуем древовидное меню в пользовательской части блога. Нам предстоит полностью переписать два файла, и немного поработать с таблицей в базе данных. О теории реализации древовидного меню мы говорили с Вами в предыдущем посте "Теория реализации древовидного меню на php". Если кто не читал этот пост, то прежде чем приступить к практике реализации обязательно прочитайте его.
Вступления для тех кто на блоге в первые. Во-первых очень рад, что Вы заглянули =) Во-вторых как мне кажется Вы ищите какую то определенную информацию, боюсь Вас разочаровать =( Данный пост, как и 95% постов на моем блоге, посвящены конкретной цели создать блог с нуля. Материал в данном посте скорее всего покажется Вам бессмысленным, так как тут правятся файлы которые были созданы пару месяцев назад, и если Вы на блоге впервые, то естественно у Вас нет этих файлов, и Вы не сможете разобраться что к чему. Тем не менее, просматривая код, вы все таки можете почерпнуть что-то для себя.
Если Вас интересует вопрос "как написать свой проект на php" то Вы попали туда куда нужно. Переходите по ссылке выше и приступайте к практическим занятиям создания простого движка блога. Кстати, хочу заметить, что мой блог работает именно на этом движке, как видите он полностью работоспособный ( пока сбоев не наблюдал =) )
Если я Вас заинтересовал то подпишитесь на RSS ленту блога через ридер, или же по почте
Первым делом я Вам расскажу, что конкретно мы сегодня будем делать
Так как мы переделываем модуль меню который написали ранее, бы ло бы полезно освежить память почитав пост "Пишем простенькое меню для нашей CMS".
Приступим. Для примера я создал три пункта. Вот как выглядит у меня сейчас таблица menu
Как видите "Подпункт 1" в колонке podmenu содержит число 3. В предыдущем посте я писал о назначение этого числа. Если кто не помнит, или не понял, то это число позволяет понять скрипту, что "Подпункт 1" является дочерним пунктом, пункта "Пункт 1". То есть если взглянуть на уже с генерированное меню, то мы увидим следующее
Приведите свою таблицу приблизительно к такому же виду. В идеале у Вас должна быть точно такая же таблица. Поэтому желательно удалить Вашу таблицу и создать новую, с помощью sql запроса который я Вам дам:
Для того, что бы удалить таблицу зайдите в структуру базы данных
Выберете таблицу menu
И внизу, во всплывающем списке выберите "С отмеченными: Удалить"
Далее заходим в структуры базы данных и жмем на кнопку "SQL"
И в появившимся поле вставляем следующий SQL запрос
CREATE TABLE IF NOT EXISTS `menu` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
`href` varchar(255) NOT NULL,
`position` int(10) NOT NULL,
`podmenu` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 AUTO_INCREMENT=5 ;
INSERT INTO `menu` (`id`, `name`, `href`, `position`, `podmenu`) VALUES
(1, 'Главная', '/', 1, 0),
(4, 'Подпункт 1', '', 3, 3),
(3, 'Пункт 1', '#', 2, 0);
Жмем "ОК". Если Вы все правильно сделали, то в Вашей базе данных будет создана таблица menu с тремя нужными нам пунктами.
Почему так важно содержимое этой таблицы? Так как в коде будет скрипт создающий
то для проверки всех этих возможностей нам необходима таблица в которой есть все возможные, тестовые ссылки.
Поэтому я настоятельно рекомендую или привести свою таблицу к такому же виду, или удалить и создать новую!!!
Надеюсь с предыдущим пунктом у Вас не возникло затруднений, если же все таки возникло, то отпишите свой вопрос, если смогу, обязательно помогу!
Теперь давайте исправим шаблон. Изменения не большие. Так как в шаблоне нам необходимо будет добавлять ссылку ( тег <a href=""></a> ) целиком то поменяем код-слова [_href] и [_link] на одно - [_station]. Вот полный код шаблона. Дополнительные пояснения ниже
<!--МЕНЮ-->
<div class="menu_title">Меню</div>
<div style="margin-left:16px;">
[_divmenu]
<div class="menu_link" style="margin-left:[_style]px;">[_station]</div>
[_podmenu]
[_divmenu]
</div>
<!--МЕНЮ-->
Код-слово - [_style] - Как видите это код-слово идет сразу же после margin-left. Не сложно догадаться, что [_style] будет содержать число, на которое будет сдвигаться наш пункт в право, образуя "дерево" =)
Код - слово - [_podmenu] - Будет содержать html код дочернего пункта. То есть вместо него будет подставлен код этого же шаблона.
Я Вам выложу полный код файла, после чего поясню работу тех двух функций которые содержатся в этом файле
function menu()
{
$result_index = mysql_query("SELECT * FROM menu ORDER BY position");//Выводим из базы данных все пункты меню
$myrow_index = mysql_fetch_array($result_index);
if($myrow_index != "")//Проверяем есть ли в базе данных записи
{//Если есть...
$sm_read = file("templates/menu.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его
preg_match("/\[_divmenu\](.*?)\[_divmenu\]/s",$sm_read,$div_menu);//Вырезаем из шаблона ту
//часть, которая будет повторяться
$i=0;//переменная позволяющая создать многомерный массив
do//Цикл do while
{
$commMASS[$i] = array($myrow_index[id],//0 - ID пункта
$myrow_index[name],//1 - Имя пункта
$myrow_index[href],//2 - Ссылка (# - нет ссылки; Пустота - Категория; "http://site.ru/page2.html" - Прямая ссылка)
$myrow_index[podmenu]);//3 - ID родительного пункта
$i++;//при каждом цикле меняем элемент многомерного массива на единицу
}
while($myrow_index = mysql_fetch_array($result_index));
$menu = station(0,$commMASS,$div_menu[1],0);//функция генерации пунктов стартовые параметры:
//0 - Вывод главных пунктов,
//$commMASS - Многомерный массив со всеми пунктами,
//$div_menu[1] - часть шаблона,
//0 - вложенность - стартовая вложенность нулевая
$menu = preg_replace("/\[_divmenu\].*?\[_divmenu\]/s",$menu,$sm_read);//Вместо [_divmenu]...[_divmenu]
//вклеиваем наш с генерированный код из $menu
}
else $menu = "";//Если записей нет, то вывести это сообщение
return $menu;//Выводим с генерированный html код
}
//-------------------------------------------------------------------
function station($stat,$commMASS,$temp,$BC)
{
for($i=0;isset($commMASS[$i]);$i++)//глобальный цикл for
{
if($commMASS[$i][3] == $stat)//если podmenu пункта равно переменной stat
{
$edd_tamp = $temp;//Так как на придется править шаблон,
//то лучше его сохранить в отдельную переменную, иначе нам придется
//пользоваться функцией file() чаще чем 1 раз, а это нагрузка на сервер
//Замены идентификаторов на переменные из базы данных
if($commMASS[$i][2] == "")$href = "<a href=\"index.php?cat=".$commMASS[$i][0]."\">".$commMASS[$i][1]."</a>";//если нет ссылки то генерируем категорию
else//если поле href не пусто
{
if($commMASS[$i][2] != "#")$href = "<a href=\"".$commMASS[$i][2]."\">".$commMASS[$i][1]."</a>";//если поле href не содержит значок "#" значит генерируем прямую ссылку
else $href = $commMASS[$i][1];//если содержит значок "#" значит пункт является не ссылкой, поэтому выводим только имя
}
$style = $BC * 10;//рассчитываем отступ от края в пикселях
$newBC = $BC + 1;//прибавляем к вложенности единицу
$podmenu = station($commMASS[$i][0],$commMASS,$temp,$newBC);//перезапускаем функцию с новыми параметрами:
//$commMASS[$i][0] - id обрабатываемого пункта
//$commMASS - массив со всеми пунктами
//$temp - шаблон
//$newBC - новый уровень вложенности
$edd_tamp = str_replace("[_podmenu]",$podmenu,$edd_tamp);//код-слово заместо которого вставляется пункты которые являются подпунктами
$edd_tamp = str_replace("[_style]",$style,$edd_tamp);//отступ от левого края в пикселях
$edd_tamp = str_replace("[_station]",$href,$edd_tamp);//Ссылка
$menu .= $edd_tamp;// Склеиваем весь с генерированный код в одну переменную
}
}
if(!isset($menu))return "";//если переменная menu не была создана то результатом будет пустота
else return $menu;//если создана переменная menu то выводим ее
}
Как видите в файле содержится две функции. О работе каждой подробнее:
Запускается генерация пунктов меню именно с этой функции. Смысл ее работы, это сбор данных из базы и превращение этих данный в многомерный массив. После, запуск второй функции и вывод результата этой функции на экран пользователя. До цикла do while изменений особых нет. Кроме появления переменной i. Она позволяет определить элемент массива ( [0],[1],[2],...,[n] ) который скрипт заполняет в данный момент.
В коде имеются комментарии так, что разобраться в работе этой функции не составит у Вас труда. Главное понять зачем все это, об этом мы говорили в предыдущем посте.
У этой функции есть параметры:
Функция проверяет каждый пункт, и обрабатывает лишь те у который podmenu ( $commMASS[$i][3] ) равен переменной stat
Ссылка, то бишь переменная href может содержать в себе ссылки трех видов.
$style содержит число которое является отступом для элемента стиля css margin-left. Расчитывается как вложенность умноженная на 10.
Для создания "дерева" используем прием перезапуска функции station() внутри самой функции station() Тем самым у нас появляется возможность вывести пункты меню которые являются не родительными, а дочерними. Перезапуск функции осуществляется с новыми параметрами:
Не думаю, что у Вас появятся какие либо вопросы по данным функциям =) В самом конце функции идут привычные нам замены код-слов, и вывод результата.
Результатом этих двух функций будет меню которое Вы можете видеть на моем блоге =) ну или на скриншоте =)
Как вы можете заметить, пункт "Главная" ведет на главную страницу. Пункт "Пункт 1" не является ссылкой. А подпункт "Подпункт 1" ведет на страницу категории. Все работает! =)
Ну что ж, еще один шаг к созданию блога с нуля пройден! В следующем посте мы займемся реализации редактирования родительных и дочерних пунктов через админ панель, так что не "переключайтесь" и подпишитесь на RSS ленту блога через ридер, или же по почте =)
Если у Вас есть какие либо вопросы, то пользуйтесь формой ниже.
Всего Вам наилучшего! У меня все!
Исходник |
Но есть предложение по оформлению - не мог бы ты сделать код с подсветкой, примерно как на этом сайте http://ruseller.com/lessons.php?rub=37&id=1392
Это бы значительно улучшило твой блог. А то строк много и приходится вводить сначала в редактор, сохранять, а потом разбираться в подсвеченном коде.
категория слесарный участок.. в ней под категории:
Подъемники
Маслосменное оборудование
а в категориях уже товары (посты так сказать)
У каждой категории есть поле "под категория", с помощью которого можно отыскать и вывести на экран вложенные пункты