Автоматическая подстановка ЧПУ в sitemap.xml и rss.xml

 

Всем добрый день! Спасибо что зашли на мой блог! Сегодня мы с Вами сделаем последние шаги к реализации ЧПУ на нашем движке. Нам осталось переделать функции генерации карты сайта и rss ленты. Добавить пару строк кода, которые позволят автоматически подставлять динамические ссылки или же ЧПУ. Так же мы немного подправим наш генератор rss ленты. Необходимо обвернуть текст новости спец тегом. Если этого не сделать могут возникнуть проблемы с некоторыми символами в анонсах, что приведет к краху всей ленты.

 

 

Для новоприбывших

 

Небольшое отступления для тех кто на блоге в первые. Материал данного поста рассчитан на аудиторию, которая уже ознакомлена с циклом статей "Создать блог с нуля". Данный цикл повествует о создание движка персонального блога. Если Вы заинтересованны в том, что бы на практике научится писать свои небольшие веб проекты, то переходите по ссылке выше и приступайте к изучению изложенного материала.

Если Вы планируете задержаться на моем блоге, то обязательно подпишитесь на RSS ленту блога через ридер, или же по почте, так Вы точно не пропустите новые заметки цикла!

 

Создаем переменную чпу в админ панели

 

Админ панель нашего движка знать не знает о том, что скрипт понимает чпу. Для того чтобы наша админ панель понимала, включен чпу режим или же нет, необходимо в главном файле (index.php) объявить переменную chpu. В будущем у нас будет специальный файл в котором будут содержаться все настройки блога, а пока объявляем переменную на прямую

Открываем админский index.php, сразу после скрипта проверки авторизации пишем следующий код:

$chpu = 1;//настройка включение выключение ЧПУ (1 - вкл; 0 - выкл)

Именно такое же объявление есть и в пользовательской части блога (тоже в файле index.php).

 

Функция sitemap() файла configpost.php

 

Открываем файл configpost.php находим в нем функцию sitemap() и приступаем к ее редактированию. Я даю Вам полный код функции, а ниже поясню что я изменил

function sitemap($site)//Генератор карты сайта
{
$header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n";//Шапка xml документа
$timeNOW = date("Y-m-d",time());//регестрируем время последнего обновление главной страницы
//начальный xml код, то есть блок с главной странице
$xmlcode = "\t<url>\n\t\t<loc>".$site."</loc>\n\t\t<lastmod>".$timeNOW."</lastmod>\n\t\t<changefreq>daily</changefreq>\n\t\t<priority>1.0</priority>\n\t</url>\n";

$smRESULT = mysql_query("SELECT id,date_b,xmlsm,nameurl FROM blog WHERE sm='1' ORDER BY id DESC");//Вытаскиваем все посты из БД
$myrow = mysql_fetch_array($smRESULT);
if($myrow != "")//если посты есть в БД
{
do//запускаем цикл
{
//приобразуем дату из БД в вид ГГГГ-ММ-ДД ( у нас в БД вот такой вид ДД/ММ/ГГГГ ЧЧ:ММ )
$datePOST = explode(" ",$myrow[date_b]);//делим дату на массив. В первом элементе массива будет ДД/ММ/ГГГГ а во втором ЧЧ:ММ
$datePOST = explode("/",$datePOST[0]);//Делим первый элемент массива на другой массив. В новом массиве будет 3 элемента. Первый содержит ДД, второй ММ и третий ГГГГ
$datePOST = $datePOST[2]."-".$datePOST[1]."-".$datePOST[0];//склеиваем элементы массива в нужном нам порядке ( ГГГГ-ММ-ДД -> третий элемент массива + второй + первый )

global $chpu;//Объявляем переменную chpu глобальной, это поможет нам вытащить ее значение без определения переменной в параметр функции
if($chpu == 0)$link = "index.php?blog=".$myrow[id];//генерируем ссылку
if($chpu == 1)$link = "post/".$myrow[nameurl];//генерируем ссылку
$xmlsm = explode("|",$myrow[xmlsm]);//режим настройку из БД (колонка xmlsm) на массив. Первый элемент будет временем обновления, второй - приоритетом

//подставляем сформированную дату и ссылку в xml код
$xmlcode .= "\t<url>\n\t\t<loc>".$site.$link."</loc>\n\t\t<lastmod>".$datePOST."</lastmod>\n\t\t<changefreq>".$xmlsm[0]."</changefreq>\n\t\t<priority>".$xmlsm[1]."</priority>\n\t</url>\n";
}
while($myrow = mysql_fetch_array($smRESULT));
$end = "</urlset>";//закрывающийся тег xml документа

$map = $header.$xmlcode.$end;//склеиваем весь xml код в одну переменную

$smFILE = fopen("../sitemap.xml", "w+");//открываем файл карты
fwrite($smFILE,$map);//записываем в нее полученный xml код
fclose($smFILE);//закрываем файл карты
}
}

Давайте по порядку:

  • Прежде чем внедрять скрипт, определяющий какие ссылки необходимо поместить в карту сайта, нужно обзавестись именем чпу из базы данных. Именно для этого мы переделываем запрос select, добавляя в выборку колонку nameurl
$smRESULT = mysql_query("SELECT id,date_b,xmlsm,nameurl FROM blog WHERE sm='1' ORDER BY id DESC");//Вытаскиваем все посты из БД
  •  Теперь для того чтобы вытащить значение переменной chpu мы ее объявим глобальной. Раньше мы протаскивали значение переменной через параметр функции, сегодня мне лень так делать поэтому я просто объявил ее глобальной...
global $chpu;//Объявляем переменную chpu глобальной, это поможет нам вытащить ее значение без определения переменной в параметр функции
  • Осталось внедрить скрипт который определит ссылку какого вида необходимо записать в карту сайта. Я заменил строчку
$link = "index.php?blog=".$myrow[id];//генерируем ссылку

 

на вот такой скрипт

		if($chpu == 0)$link = "index.php?blog=".$myrow[id];//генерируем ссылку
if($chpu == 1)$link = "post/".$myrow[nameurl];//генерируем ссылку

На этом редактирование функции законченно. Теперь в зависимости от переменной chpu в карту сайта попадет либо динамическая ссылка, либо чпу

 

результат работы функции sitemap()

 

 

Функция rss() файла configpost.php

 

Находим, в том же файле, функцию rss() и заменяем ее на вот такую:

function rss($site)
{
$rssHEADER = mysql_query("SELECT * FROM page WHERE id='1'");//Вытаскиваем инфу о сайте
$myrowHEADER = mysql_fetch_array($rssHEADER);

//формируем шапку
$header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rss version=\"2.0\">\n\t<channel>\n\t\t<title>".$myrowHEADER[title]."</title>\n\t\t<link>".$site."</link>\n\t\t<description>".$myrowHEADER[meta_d]."</description>\n\t\t<language>ru-ru</language>\n";//Шапка xml документа

$rssRESULT = mysql_query("SELECT id,date_b,title,text,nameurl FROM blog WHERE rss='1' ORDER BY id DESC LIMIT 5");//Вытаскиваем 5 постов из БД
$myrow = mysql_fetch_array($rssRESULT);

if($myrow != "")//если есть посты которые нужно поместить в rss ленту
{
do
{
//приобразуем дату из БД в вид ГГГГ-ММ-ДД ( у нас в БД вот такой вид ДД/ММ/ГГГГ ЧЧ:ММ )
$datePOST = explode(" ",$myrow[date_b]);//делим дату на массив. В первом элементе массива будет ДД/ММ/ГГГГ а во втором ЧЧ:ММ
$dateMS = $datePOST[1];//сохраняем минуты и сек в отдельной переменной
$datePOST = explode("/",$datePOST[0]);//Делим первый элемент массива на другой массив. В новом массиве будет 3 элемента. Первый содержит ДД, второй ММ и третий ГГГГ
$dateUNIX = strtotime($datePOST[0]."-".$datePOST[1]."-".$datePOST[2]);//Формируем дату в виде ДД-ММ-ГГГГ после чего превращаем ее в целое число
$datePOST = date("D, d M Y ",$dateUNIX);//превращаем дату в вид Thu, 16 Feb 2012 (пример)
$datePOST = $datePOST.$dateMS.":01 GMT";//пристыковываем к дате еще и время (пример Thu, 16 Feb 2012 04:43:01 GMT)

global $chpu;//Объявляем переменную chpu глобальной, это поможет нам вытащить ее значение без определения переменной в параметр функции
if($chpu == 0)$link = $site."index.php?blog=".$myrow[id];//генерируем ссылку
if($chpu == 1)$link = $site."post/".$myrow[nameurl];//генерируем ссылку

$txt = explode("<p>[end]</p>",$myrow[text]);//отделяем анонс от текста поста
$txt = strip_tags($txt[0]);//чистим анонс от html кода
$txt = "<![CDATA[".$txt."]]>";//Обхватываем текст спец тегом, что бы текст воспринимался как текст, а не как разметка

//генерируем xml код
$xmlcode .= "\t\t<item>\n\t\t\t<title>".$myrow[title]."</title>\n\t\t\t<link>".$link."</link>\n\t\t\t<description>".$txt."</description>\n\t\t\t<pubDate>".$datePOST."</pubDate>\n\t\t</item>\n";
}
while($myrow = mysql_fetch_array($rssRESULT));

$end = "\t</channel>\n</rss>";//закрываем теги xml документа
$result = $header.$xmlcode.$end;//склеиваем части xml кода

$result = iconv("CP1251","UTF-8",$result);//принудительно меняем кодировку на utf8

$rssFILE = fopen("../rss/rss.xml", "w+");//открываем файл rss ленты
fwrite($rssFILE,$result);//записываем в него полученный xml код
fclose($rssFILE);//закрываем rss ленту
}
}

Точно так же по порядку

  • Для начала я изменил шапку нашего xml файла (переменная header). если быть конкретнее то кодировку. RSS ленту лучше держать в кодировке UTF-8
$header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rss version=\"2.0\">\n\t<channel>\n\t\t<title>".$myrowHEADER[title]."</title>\n\t\t<link>".$site."</link>\n\t\t<description>".$myrowHEADER[meta_d]."</description>\n\t\t<language>ru-ru</language>\n";//Шапка xml документа 
  • Аналогично с функцией sitemap() нам необходимо переделать select запрос, а именно добавить выборку колонки nameurl
$rssRESULT = mysql_query("SELECT id,date_b,title,text,nameurl FROM blog WHERE rss='1' ORDER BY id DESC LIMIT 5");//Вытаскиваем 5 постов из БД
  • Далее объявить переменную chpu глобальной
global $chpu;//Объявляем переменную chpu глобальной, это поможет нам вытащить ее значение без определения переменной в параметр функции
  • Дальше я вставил скрипт определения ссылки. Заменил вот эту строчку
$link = $site."index.php?blog=".$myrow[id];//генерируем ссылку

на более сложную. Что касается функционала смены ссылок с динамических на чпу, то все аналогично функции sitemap()

		if($chpu == 0)$link = $site."index.php?blog=".$myrow[id];//генерируем ссылку
if($chpu == 1)$link = $site."post/".$myrow[nameurl];//генерируем ссылку

Но на этом не все, как я уже говорил необходимо, текст анонса поста обвернуть в спец тег. Этот спец тег превращает текст в текст. Если не произвести данный ап функции то в дальнейшем можно столкнуться с неадекватной реакции например на символ "&nbsp;". Если в тексте попадается данный символ, и если текст не обвернут в спец тег, то в ленте анонсов видно не будет!

 

Глюк без спец тега в rss ленте

 

Как видите через браузер ничего не видно, а сам код есть. Происходит это потому что браузер считает, что в тегах <description></description> находится разметка, а не текст.

  • Так вот, для того чтобы избежать данной проблемы я сразу после очистки анонса от html тегов разместил вот такую строчку
$txt = "<![CDATA[".$txt."]]>";//Обхватываем текст спец тегом, что бы текст воспринимался как текст, а не как разметка

<![CDATA[Текст]]> и есть тот самый спец тег

  • Ну и на по следок необходимо вставить, сразу после склеивания всех частей xml, строчку кода, которая в принудительно режиме сменит кодировку в utf-8
$result = iconv("CP1251","UTF-8",$result);//принудительно меняем кодировку на utf8

 

результат работы функции rss()

 

 

Заключение

 

Ну что ж, если я ничего не забыл, то теперь наш блог полностью совместим с чпу режимом, с чем я Вас и поздравляю!

Я пока еще не думал чем мы займемся в следующих заметках, так что не "переключайтесь" и подпишитесь на RSS ленту блога через ридер, или же по почте, так Вы точно не пропустите новые заметки цикла!

Всего Вам наилучшего! У меня все!

Исходник
 

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

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

Ваше имя *
Сайт
Ваш E-mail *
Ваше сообщение *
 
Илья, 07 Декабря 2016 г. 19:42 пишет:
Читатель

Здравствуйте, дорогой Rio-Shaman! Я хочу у вас спросить, в одной из своих статей вы писали о том, что пользуетесь вместо сделанного ранее BB-редактора, каким-то готовым редактором, TInyMCE(не помню) вроде бы. В комментариях сейчас используются как раз BB-коды, Вы сами сделали этот редактор BB-кодов(эдакий ап прошлого) или установили готовый?? Плюс ещё вопрос: после нажатия на BB-код он автоматически подставляется на место курсора, как это реализовано(насколько я понимаю, это JS)? Весь интернет перерыл, ответьте пожалуйста! Заранее благодарю :)

ЗЫ я школьник 15-летний, за 4-5 месяцев написал свой движок с множеством дополнительных модулей... Сейчас готовлю мега-большой АП своего движка) Планов тьма, делаю по вашим урокам, так как для меня это самый легкий способ :) За все время работы в области веб-программирования я овладел на среднем уровне PHP, JS(jquery в частности), HTML5, CSS3 ну и конечно же MYSQL(SQL). Если у вас есть предложения по сотрудничеству, то прошу написать мне на e-mail! Ещё раз заранее спасибо за ответы на вопросы выше!

Мой сайт: Тур-Алтай.РУ - твой гид в сфере туризма.

Илья, 07 Декабря 2016 г. 19:46 пишет:
Читатель
Извините за спам! интернет лаганул, отправил по ошибке 3 раза один и тот же коммент :(
Алексей, 07 Декабря 2016 г. 19:53 пишет:
Автор
Доброго времени суток.
Для формы комментариев я использую уже готовый бб редактор. ТиниМСЕ я использую в админке, для написание статей.
Ответ для пользователя: Илья
Илья, 08 Декабря 2016 г. 13:01 пишет:
Читатель
Спасибо большое за ответ! :) Вы не могли бы сказать название bb-редактора или вы сами его сделали?… извините могу тупить )
Ответ для пользователя: Алексей
Алексей, 09 Декабря 2016 г. 11:30 пишет:
Автор
В комментариях я использую markItUp
Ответ для пользователя: Илья
Илья, 09 Декабря 2016 г. 20:52 пишет:
Читатель
Спасибо большое) Если вам нужны помощники, пишите мне на е-маил, я отлично справляюсь с вашим подходом к созданию модулей и сайтов в целом :)
Ответ для пользователя: Алексей