Пишем редактор меню для нашей CMS

 

Доброго времени суток дорогой читатель Блога RS! Сегодня я решил посветить пост циклу статей "разработка cms", а именно продолжим писать нашу админку. В план этого поста входит создание редактора меню, для того что бы мы могли добавлять на наш блог новые рубрики, редактировать и удалять старые. Так же обучим редактор менять пункты меню местами. За сегодня нам необходима создать как минимум три страницы, и написать тонну кода. Приступим...

 

 

Ну насчет тонны я конечно немного преувеличил Просто в редакторе много мелочей, которые очень сложно объяснить. Давайте сначала наметим цели, то есть введен некое тех задание, конкретику!

 

Цель

 

  • В нашей пользовательской части блога выборка пунктов меню производится по умолчанию, то есть по id. Необходимо добавить новую колонку в которой будет производится нумерация порядка вывода пунктов
  • На нашей главной страницы админки нет кнопки на редактор ( правда самого редактора тоже пока нет ) поэтому нам предстоит отредактировать главную страницу
  • Необходимо реализовать список всех пунктов меню. Значит нам потребуется шаблон, и код php для вывода такого списка
  • Создать два шаблона с формой, для редактирования пункта меню и добавления пункта в БД. Само собой нужны будут php обработчики для этих форм
  • Необходимо ввести систему сортировки пунктов меню в админ панели. В эту систему входит выборка пунктов по определенной колонки БД.
  • Реализовать удаление пункта меню.
  • Реализовать кнопочки для воздействия на позицию нашего пункта меню. Раз есть кнопочки то должен быть и обработчик, который будет менять позиции в БД

 

Подготовка

 

Вот как выглядит главная страница админки

Вот как выглядит список меню

Как видите нам необходимо несколько графических файлов. Вот папка с нужной нам графикой. Изображения помещаются в папку img в каталоге admin

 

Изменяем выборку меню в пользовательской части

 

Для начала нам необходимо добавить новую колонку в таблицу menu нашей БД. Так же необходимо пронумеровать строки этой колонки от 1 до N

  • Заходим в "Структуры" таблицы menu
  • Выбираем "добавить после href" жмем ОК
  • Заполняем поля, жмем "Сохранить"

  • Далее пронумеруйте строки от 1 до N ( В моем случае от 1 до 3 )

Теперь отредактируем функцию menu() в модуле menu.php, что находится в пользовательской части нашего проекта

Отредактируем строку sql запроса так

$result_index = mysql_query("SELECT * FROM menu ORDER BY position");//Выводим из базы данных все пункты меню

Теперь наши пункты меню будут выводится в том порядке в котором нам необходимо

 

Редактируем главную страницу админки

 

Для этого нам необходимо открыть шаблон меню админки - menu.html и добавить новую ссылку

<table width="600px" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=add_content"><img src="img/add_content.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=all_content"><img src="img/all_content.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=all_menu"><img src="img/edd_menu.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center">&nbsp;</td>
<td width="100px" height="100px" valign="top" align="center">&nbsp;</td>
<td width="100px" height="100px" valign="top" align="center">&nbsp;</td>
</tr>
</table>

На главной страницы должна появится новая ссылка

 

Реализуем в админ панели список пунктов меню

 

Нам понадобится шаблон, который чем то схож с шаблоном вывода списка постов, и php код. Начнем с шаблона

<table width="600px" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td valign="top" height="30px" colspan="4"><a href="?page=add_menu"><img src="img/add.jpg" border="0px"></a></td>
</tr>
[_while]
<tr>
<td valign="top"><a style="font-weight:100;" href="?page=edd_menu&edd_menu=[_id]">[_name]</a></td>
<td width="15px">[_up]<a href="?page=edd_menu&up_menu=[_id]"><img src="img/up.jpg" border="0px"></a>[_up]</td>
<td width="15px">[_down]<a href="?page=edd_menu&down_menu=[_id]"><img src="img/down.jpg" border="0px"></a>[_down]</td>
<td width="30px" align="right"><a href="?page=edd_menu&del_menu=[_id]"><img src="img/del.jpg" border="0px"></a></td>
</tr>
[_while]
</table>

В шаблоне присутствуют все необходимые нам ссылки. Ссылки в свою очередь берутся из головы. Хочу пояснить насчет код слов [_up] и [_down]. Эти код слова будут помогать нам исключать кусочки html кода из шаблона если это вдруг понадобится. А это нам понадобится! Так как в нашем редакторе меню будет возможность двигать пункты вверх или вниз, наступит такая ситуация когда один из пунктов будет находится в самом вверху, то есть двигать на верх его уже нельзя! А значит кнопочку необходимо удалить из шаблона, вот тут на помощь и придут наши код слова.

Я назвал этот шаблон allmenu.html и помести в папку с шаблонами для админ панели.

Теперь пришло время создать модуль который выведет нам этот список на экран

function allmenu()//Функция вывода списка меню
{
$sm_read = file("templates/allmenu.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его

preg_match("/\[_while\](.*?)\[_while\]/s",$sm_read,$tamp_while);//Находим в шаблоне тут часть, которую будет ду вайлить

$result_index = mysql_query("SELECT * FROM menu ORDER BY position");//Выводим из базы данных пункты меню
$myrow_index = mysql_fetch_array($result_index);
$col = mysql_num_rows($result_index);//Узнаем общее количество пунктов в базе данных

do
{
$copy_tamp = $tamp_while[1];//Сохраняем ту часть которая будет повторяться в отдельную переменную

//Если обрабатываем первый пункт, то запрещаем вывод кнопки "поднять пункт вверх"
if($myrow_index[position] == 1)$copy_tamp = preg_replace("/\[_up\].*?\[_up\]/s","&nbsp;",$copy_tamp);
else $copy_tamp = str_replace("[_up]","",$copy_tamp);//Если пункт не первый, то удаляем код слово из шаблона

//Если обрабатываем последний пункт, то запрещаем вывод кнопки "опустить пункт вниз"
if($myrow_index[position] == $col)$copy_tamp = preg_replace("/\[_down\].*?\[_down\]/s","&nbsp;",$copy_tamp);
else $copy_tamp = str_replace("[_down]","",$copy_tamp);//Если пункт не последний, то удаляем код слово из шаблона

//Делаем замены код-слов
$copy_tamp = str_replace("[_name]",$myrow_index[name],$copy_tamp);//Название пункта
$copy_tamp = str_replace("[_id]",$myrow_index[id],$copy_tamp);//ID пункта

$list .= $copy_tamp;//Объединяем результат в одну переменную
}
while($myrow_index = mysql_fetch_array($result_index));

$sm_read = preg_replace("/\[_while\].*?\[_while\]/s",$list,$sm_read);//Вставляем в щаблон список пунктов

return $sm_read;//Выводим с генерированный html код
}

Весь код за комментирован, я думаю тут ничего сложного для Вас нет! Логика тут довольно проста.

  • Вытаскиваем все пункты меню.
  • После мы копируем из шаблона кусочек кода который будет повторятся.
  • Проверяем пункт, первый он или последний, если одно из условие верно, то удаляем кнопочку из скопированного кусочка шаблона
  • Заменяем в этой копии код слова на данные из БД.
  • На по следок все это соединяется и выводится на экран

Эту функцию я сохранил в новом файле, назвал файл eddmenu.php, поместил его в модули админ панели.

Теперь что бы увидеть результат на экране, мы должны подключить модуль к нашему основному файлу index.php. Поместите этот кусочек кода

//РЕДАКТОР МЕНЮ
if($page == "all_menu")
{
include("moduls/eddmenu.php");
if($page == "all_menu")$txt = allmenu();
}
//РЕДАКТОР МЕНЮ

перед строкой

include("templates/index.html");

Если на главной странице админ панели щелкнуть по кнопке "меню" то Вас перенесет вот на эту страницу

 

Реализуем добавление пункта

 

Для этого необходимо написать обработчик и шаблон. Начнем с шаблона

<table width="600px" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td valign="top" align="center">
<form action="index.php?page=add_menu" method="post" name="form">
<br>
<input style="width:600px;" name="addname_p" type="text" value="Введите имя пункта">
<br>
<input style="width:600px;" name="addhref_p" type="text" value="Введите ссылку пункта">
<br>
<br><br><input type="submit" value="Добавить пункт">
</form>
</td>
</tr>
</table>

Ничего сложного обычная форма из двух полей и кнопки

Далее напишем php код для вывода нашей формы на экран. Для этого создадим функцию addmenu() в новом файле addmenu.php

function addmenu()//Функция вывода формы редактирования меню
{
$sm_read = file("templates/addmenu.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его

return $sm_read;//Выводим с генерированный html код
}

Просто подключаем шаблон и выводим на экран. Далее реализуем подключение это модуля. Заходим в файл index.php и добавляем вот этот кусочек кода

//ДОБАВЛЯЕМ ПУНКТ
if($page == "add_menu")
{
include("moduls/addmenu.php");
$txt = addmenu();
}
//ДОБАВЛЯЕМ ПУНКТ

Сразу после подключения редактора меню. Кстати, значение переменной page я узнаю из ссылок которые брал из головы

Теперь давайте напишем обработчик для добавление пункта меню в БД

//ДОБАВЛЯЕМ ПУНКТ МЕНЮ
if(isset($_POST['addname_p']))$addname_p = $_POST['addname_p'];
if(isset($_POST['addhref_p']))$addhref_p = $_POST['addhref_p'];
if(isset($addname_p) AND isset($addhref_p))
{
$result_index = mysql_query("SELECT COUNT(*) FROM menu");//Выводим из базы данных пункты меню
$myrow_index = mysql_fetch_array($result_index);

$col = $myrow_index[0];//Узнаем общее количество пунктов в базе данных
$col++;

$result_add_menu = mysql_query ("INSERT INTO menu (name,href,position)
VALUES ('$addname_p','$addhref_p','$col')");

header("location: index.php?page=all_menu");//Перенаправление
exit;//на страницу пунктов меню
}
//ДОБАВЛЯЕМ ПУНКТ МЕНЮ

Этот обработчик я поместил в модуль addmenu.php. Пункт по умолчанию займет самую последнюю позицию среди пунктов

 

Реализуем редактирование пункта

 

Для реализации редактора нам необходим шаблон и обработчик. Как всегда начну с шаблона

<table width="600px" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td valign="top" align="center">
<form action="index.php?page=edd_menu&edd_menu=[_id]" method="post" name="form">
<br>
<input style="width:600px;" name="name_p" type="text" value="[_name]">
<br>
<input style="width:600px;" name="href_p" type="text" value="[_href]">
<br>
<br><br><input type="submit" value="Редактировать пункт">
</form>
</td>
</tr>
</table>

Форма редактирования и форма добавления выглядят одинаково! Разница лишь в атрибуте name, action и value у кнопки.

Теперь напишем функцию вывода этого шаблона на экран. Функция пишется в модуле eddmenu.php

function eddmenu($edd_menu)//Функция вывода формы редактирования меню
{
$sm_read = file("templates/eddmenu.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его

$result_index = mysql_query("SELECT name,href FROM menu WHERE id = '$edd_menu'");//Выводим из базы данных пункт меню
$myrow_index = mysql_fetch_array($result_index);

$sm_read = str_replace("[_name]",$myrow_index[name],$sm_read);//Название пункта
$sm_read = str_replace("[_href]",$myrow_index[href],$sm_read);//Ссылка пункта
$sm_read = str_replace("[_id]",$edd_menu,$sm_read);//ID пункта

return $sm_read;//Выводим с генерированный html код
}

Подключим новую возможность модуля eddmenu.php. Для этого идем в файл index.php и редактируем условие подключения этого модуля

//РЕДАКТОР МЕНЮ
if($page == "all_menu" || $page == "edd_menu")
{
include("moduls/eddmenu.php");
if($page == "all_menu")$txt = allmenu();
if($page == "edd_menu")$txt = eddmenu($edd_menu);
}
//РЕДАКТОР МЕНЮ

Надеюсь тут все ясно.

Теперь создадим обработчик редактора добавляя вверху новые строки кода в файле eddmenu.php

//РЕДАКТИРУЕМ ПУНКТ МЕНЮ
if(isset($_POST['name_p']))$name_p = $_POST['name_p'];
if(isset($_POST['href_p']))$href_p = $_POST['href_p'];
if($_GET['edd_menu'])$edd_menu = $_GET['edd_menu'];
if(isset($name_p) AND isset($href_p))
{
$edd_punct = mysql_query ("UPDATE menu SET name='$name_p',href='$href_p' WHERE id='$edd_menu'");

header("location: index.php?page=all_menu");//Перенаправление
exit;//на страницу пунктов меню
}
//РЕДАКТИРУЕМ ПУНКТ МЕНЮ

Тут тоже все просто У меня все работает

 

Реализуем удаления пункта меню

 

Для это в модуле eddmenu.php после кода отвечающего за редактирование пункта вставить вот этот код

//УДАЛЕНИЕ ПУНКТА МЕНЮ
if($_GET['del_menu'])$del_menu = $_GET['del_menu'];
if(isset($del_menu))
{
$result_del_menu = mysql_query ("DELETE FROM menu WHERE id='$del_menu'");//удаляем пункт меню

$res_delmenu = mysql_query("SELECT id FROM menu ORDER BY position");//Выводим из базы данных пункт меню сортируя их по колонке position
$my_delmenu = mysql_fetch_array($res_delmenu);

$new_pos_menu = 1;
do
{
$edd_pos_menu = mysql_query ("UPDATE menu SET position='$new_pos_menu' WHERE id='$my_delmenu[id]'");
$new_pos_menu++;
}
while($my_delmenu = mysql_fetch_array($res_delmenu));

header("location: index.php?page=all_menu");//Перенаправление
exit;//на страницу пунктов меню
}
//УДАЛЕНИЕ ПУНКТА МЕНЮ

В этом обработчике помимо просто удаление пункта из БД идет обновление позиций. Обновление реализуется простым циклом ду вайл, ничего сложного!

 

Реализуем изменения позиций пунктов меню

 

Необходимо вставить вот этот код

//ДВИГАЕМ ПУНКТ МЕНЮ ВВЕРХ/ВНИЗ
if($_GET['up_menu'])$up_menu = $_GET['up_menu'];
if($_GET['down_menu'])$down_menu = $_GET['down_menu'];
if(isset($up_menu) || isset($down_menu))
{
if(isset($up_menu))//Если двигаем вверх
{
$info_menu = mysql_query("SELECT position FROM menu WHERE id='$up_menu'");//Вытаскиваем значение колонки position из строки где id = пункту который двигаем
$myrow_info_menu = mysql_fetch_array($info_menu);
$new_pos = $myrow_info_menu[position] - 1;//Изменяем значение позиции
$nav_id = $up_menu;//Сохраняем id пункта который двигаем в отдельную переменную
}
if(isset($down_menu))//Если двигаем вниз
{
$info_menu = mysql_query("SELECT position FROM menu WHERE id='$down_menu'");//Вытаскиваем значение колонки position из строки где id = пункту который двигаем
$myrow_info_menu = mysql_fetch_array($info_menu);
$new_pos = $myrow_info_menu[position] + 1;//Изменяем значение позиции
$nav_id = $down_menu;//Сохраняем id пункта который двигаем в отдельную переменную
}

$old_pos = $myrow_info_menu[position];//Заносим в отдельную переменную значение позиции двигаемого пункта

//Напишу для Вас конкретный пример. Мы двигаем пункт с позиции 3 на позицию 2
//То есть мы двигаем пункт вверх.
//После того как мы определили все переменные выше ( то есть рассчитали новые позиции и сохранили старые )
$new_pos_db = mysql_query ("UPDATE menu SET position='$old_pos' WHERE position='$new_pos'");//Заносим в пункт который сейчас на позиции 2 его новую позицию, то есть 3
$old_pos_db = mysql_query ("UPDATE menu SET position='$new_pos' WHERE id='$nav_id'");//Заносим в пункт который мы двигаем его новую позицию, то есть 2
header("location: index.php?page=all_menu");//Перенаправление
exit;//на страницу пунктов меню
}
//ДВИГАЕМ ПУНКТ МЕНЮ ВВЕРХ/ВНИЗ

сразу после обработчика удаление пунктов. Я за комментировал строчки, и даже написал пример, но, все же поясню все еще раз

Давайте на конкретном примере рассмотрим работу нашего кода. Нам необходимо пункт "Об Авторе" сдвинуть вверх


После нажатие на галочку вверх, наш скрипт начинает обработку.

  • Для начала он рассчитает новую позицию для пункта который нам необходимо сдвинуть вверх.
  • Потом он сохранит id двигаемого пункта
  • И сохранит позицию в которой находится в данный момент наш пункт

Далее код, по переменной $new_pos, то есть по новой позиции нашего пункта, находит строчку в БД и редактирует ей колонку position вставляя туда значение переменной $old_pos, то есть позицию нашего двигаемого пункта

После этого скрипт по переменной $nav_id находит двигаемый пункт в БД и заменяет в нем position на значение переменной $new_pos, то есть назначает пункту новую позицию

На этом действие скрипта заканчивается

 

Заключение

 

Ну что ж, на этом я заканчиваю! За сегодня мы с Вами создали полностью рабочий редактор меню, теперь у Вас есть возможность, создавать новые пункты, менять их местами, делать из них категории, удалять и редактировать их. Движок на котором создан мой блог, был вывешен в сеть именно на этой стадии, так, что еще чуть чуть, и мы создадим полноценно рабочий продукт! Поэтому следите за новостями, и подпишитесь на мой блог

Если есть какие вопросы, или просто отзывы, критика, то оставляйте комментарии, с удовольствием почитаю!

Удачи Вам, на сегодня у меня все!

Исходник
 

Возможно Вам будут интересны следующие заметки

Комментарии (15)

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
Алекс, 23 Декабря 2011 г. 22:48 пишет:
Читатель
Долго буду переваривать =) интересная статья.
Rio-Shaman, 23 Декабря 2011 г. 23:40 пишет:
Автор
Ну тут ничего сложного нет =)
Кстати, Вы пишите с нового почтового ящика, для которого стоит статус "Гость блога" Я повысил и этот почтовый ящик до "Читателя"
Ответ для пользователя: Алекс
Алекс, 24 Декабря 2011 г. 18:06 пишет:
Читатель
Да спасибо за статус, просто недавно пробовал gravatar подключить на почту итого ...@mail.ru он не поддерживает, а @gmail.com поддерживает. Пришлось перестраиваться =)
Димон, 23 Апреля 2012 г. 14:46 пишет:
Читатель
Алексей! День добрый! Я скинул вам на мыло письмо! Прочтите пожалуйста!
Алексей, 24 Апреля 2012 г. 17:08 пишет:
Читатель
Класс статья)
ifelse, 12 Января 2013 г. 22:34 пишет:
Читатель
Добрый день!Все бы ничего,но как создать страницу? Т.к. нажимая на пункт меню он переадресовывает на 404 страницу.
japson, 16 Января 2014 г. 14:45 пишет:
Гость
Rio-Shaman, вы очень хороший человек. спасибо вам за этот курс. Я обязательно вам пришлю ссылку,что получилось. Я поэт, музыкант. Если разместите свой денежный ящик, возблагодарил бы. Да думаю многие так бы поступили.
я, 22 Февраля 2014 г. 20:16 пишет:
Гость
На главной странице админ панели щелкаю по кнопке "меню", и меня переносит на чистую страницу, не выдает пункты меню..
Алексей, 24 Февраля 2014 г. 09:52 пишет:
Автор
И ошибок никаких нет? Если так то Вы что-то упустили...
Ответ для пользователя: я
Я, 24 Февраля 2014 г. 10:37 пишет:
Гость
Все уже нормально, да маленькую ошибку допустила
Дмитрий, 25 Февраля 2014 г. 16:04 пишет:
Читатель
Приветствую Вас Алексей! Сделал этот пункт и всё работает (при чём делаю изначально со своим дизайном и в UTF-8)
Короче всё супер
Я, 26 Февраля 2014 г. 21:44 пишет:
Гость
вот в этом куске в index.php
//РЕДАКТОР МЕНЮ
 if($page == "all_menu"  || $page == "edd_menu"){//если находимся на странице ?page=all_menu
  include("moduls/eddmenu.php");
  if($page == "all_menu") $txt = allmenu();// вывод  списка пунктов меню
   if($page == "edd_menu") $txt = eddmenu($edd_menu); 
 }
 //РЕДАКТОР МЕНЮ
при вызове функции eddmenu($edd_menu) , где определяется значение переменной $edd_menu??
Алексей, 27 Февраля 2014 г. 09:54 пишет:
Автор
Вот тут:
//РЕДАКТИРУЕМ ПУНКТ МЕНЮ
if(isset($_POST['name_p']))$name_p = $_POST['name_p'];
if(isset($_POST['href_p']))$href_p = $_POST['href_p'];
if($_GET['edd_menu'])$edd_menu = $_GET['edd_menu']; // Вот объявление переменной $edd_menu
if(isset($name_p) AND isset($href_p))
{
    $edd_punct = mysql_query ("UPDATE menu SET name='$name_p',href='$href_p' WHERE id='$edd_menu'");
    
    header("location: index.php?page=all_menu");//Перенаправление
    exit;//на страницу пунктов меню
}
//РЕДАКТИРУЕМ ПУНКТ МЕНЮ
Ответ для пользователя: Я
Роман, 17 Января 2016 г. 00:39 пишет:
Гость
Никак не могу понять как вставлять новые пункты меню(((
Как именно нужно писать ссылку? Покажите, пожалуйста, наглядный пример допустим как подключить контакты?
Заранее спасибо!)
Алексей, 17 Января 2016 г. 20:42 пишет:
Автор
Данный редактор меню позволяет лишь сослаться на какую либо страницу, а не создать ее (страницу).
Ответ для пользователя: Роман