Автоматическая генерация sitemap.xml в CakePHP 1.2

November 24, 2008 | By admin | Filed in: CakePHP, Переводы.

Планирую размещать в блоге переводы статей из CakePHP Super Feed. Данное начинание открывает пост, оригинал которого находится здесь – http://mentalramblings.info/posts/view/automatic-sitemap-generation-with-CakePHP-1.2

Итак.

Весьма важным фактором для веб-сайта является его индексируемость поисковыми системами. Когда я перешел на CakePHP 1.2, то обнаружил, что файл sitemap.xml у моего сайта отсутствует. Ну, и чтобы не править руками карту сайта каждый раз, когда я добавляю пост в блог, я решил поискать автоматизированное решение.

Нужно сказать, что данной проблемой для кейка никто особо не занимался. Существует много решений для PHP, но все они показались мне чересчур громоздкими. Поэтому, после прочтения краткого туториала от Chris Hartjes все оказалось очень просто!

Покопавшись в документах от Google, я нашел такую вот полезную  информацию.

The Sitemap Protocol format consists of XML tags. All data values in a Sitemap must be entity-escaped. The file itself must be UTF-8 encoded.

A sample Sitemap that contains just one URL and uses all optional tags is shown below. The optional tags are in italics.


 <?xml version="1.0" encoding="UTF-8"?>   < urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">    < url>     < loc>http://www.example.com/</loc>     < lastmod>2005-01-01</lastmod>     < changefreq>monthly</changefreq>     < priority>0.8</priority>    </url>   </urlset>

И далее,

The Sitemap must:

  • Begin with an opening <urlset> tag and end with a closing </urlset> tag.
  • Include a <url> entry for each URL as a parent XML tag.
  • Include a <loc> child entry for each <url> parent tag.

Очень интересно. Так как же нам применить все это к нашему сайту? Очень просто – используя пример  Криса и немного магии маршрутов кейка.

Ниже приведено содержимое файла /app/controllers/sitemaps_controller.ctp.

</pre>
<pre><?php
/**
* Sitemap Generator
*  <?xml version="1.0" encoding="UTF-8"?>
*  < urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
*      < url>
*          < loc>http://www.example.com/</loc>
*          < lastmod>2005-01-01 00:00:00</lastmod>
*          < changefreq>monthly</changefreq>
*          < priority>0.8</priority>
*      </url>
*  </urlset>
*
* The Sitemap must:
* Begin with an opening <urlset> tag and end with a closing </urlset> tag.
* Include a <url> entry for each URL as a parent XML tag.
* Include a <loc> child entry for each <url> parent tag.
*
*/
class SitemapsController extends AppController
{</pre>
<pre>var $components = array('RequestHandler');
var $helpers = array('Time', 'Xml');
var $name = 'Sitemaps';
var $uses = array('Category', 'Post');</pre>
<pre>function sitemap ()
{
Configure::write ('debug', 0);
$cats = $this->Category->find('all', array('fields' => array('nicename', 'modified')), null, -1);
$posts = $this->Post->find('all', array('fields' => array('name', 'modified')), null, -1);
$this->set(compact('cats','posts'));
$this->RequestHandler->respondAs('xml');
$this->viewPath .= '/xml';
$this->layoutPath = 'xml';
}
}
?></pre>
<pre>

Далее, наше представление (файл /app/views/sitemaps/xml/sitemap.ctp)


<urlset xmlns=<span class="st0">"http://www.sitemaps.org/schemas/sitemap/0.9"</span>>
<span class="kw2"><?php</span> <span class="kw1">foreach</span> <span class="br0">(</span><span class="re0">$cats</span> <span class="kw1">as</span> <span class="re0">$cat</span><span class="br0">)</span>:<span class="kw2">?></span>
<url>
<loc>http:<span class="co1">//mentalramblings.info/categories/view/<?php echo $cat['Category']['nicename']; ?></loc></span>
<lastmod><?php <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$time</span>-><span class="me1">toAtom</span><span class="br0">(</span><span class="re0">$cat</span><span class="br0">[</span><span class="st0">'Category'</span><span class="br0">]</span><span class="br0">[</span><span class="st0">'modified'</span><span class="br0">]</span><span class="br0">)</span>; ?></lastmod>
<changefreq>weekly</changefreq>
<priority><span class="nu0">0.7</span></priority>
</url>
<span class="kw2"><?php</span> <span class="kw1">endforeach</span>; <span class="kw2">?></span>
<span class="kw2"><?php</span> <span class="kw1">foreach</span> <span class="br0">(</span><span class="re0">$posts</span> <span class="kw1">as</span> <span class="re0">$post</span><span class="br0">)</span>:<span class="kw2">?></span>
<url>
<loc>http:<span class="co1">//mentalramblings.info/posts/view/<?php echo $post['Post']['name']; ?></loc></span>
<lastmod><?php <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$time</span>-><span class="me1">toAtom</span><span class="br0">(</span><span class="re0">$post</span><span class="br0">[</span><span class="st0">'Post'</span><span class="br0">]</span><span class="br0">[</span><span class="st0">'modified'</span><span class="br0">]</span><span class="br0">)</span>; ?></lastmod>
<changefreq>weekly</changefreq>
<priority><span class="nu0">0.8</span></priority>
</url>
<span class="kw2"><?php</span> <span class="kw1">endforeach</span>; <span class="kw2">?></span>
<url>
<loc>http:<span class="co1">//mentalramblings.info/pages/home</loc></span>
<lastmod><span class="nu0">2008</span><span class="nu0">-01</span>-27T20:<span class="nu0">41</span>:52Z</lastmod>
<changefreq>monthly</changefreq>
<priority><span class="nu0">0.5</span></priority>
</url>
<url>
<loc>http:<span class="co1">//mentalramblings.info/pages/aboutus</loc></span>
<lastmod><span class="nu0">2008</span><span class="nu0">-01</span>-27T20:<span class="nu0">41</span>:52Z</lastmod>
<changefreq>monthly</changefreq>
<priority><span class="nu0">0.5</span></priority>
</url>
<url>
<loc>http:<span class="co1">//mentalramblings.info/contacts/contactus</loc></span>
<lastmod><span class="nu0">2008</span><span class="nu0">-01</span>-27T20:<span class="nu0">41</span>:52Z</lastmod>
<changefreq>monthly</changefreq>
<priority><span class="nu0">0.5</span></priority>
</url>
</urlset>

Здесь мы просто проходим в цикле foreach по данным, полученным в контроллере. Единственная сложность заключается в том, чтобы определить, какой формат времени нужен Гуглу для элемента <lastmod>. В итоге здесь весьма кстати оказалась функция CakePHP $time->toAtom().

В заключение я добавил в файл маршрутов (/app/config/routes.php) следующую строку


Router::connect('/sitemap.xml', array('controller' => 'sitemaps', 'action' => 'sitemap'));

для того, чтобы файл был доступен из корня сайта.

На этом все.

[от меня] Следует добавить, что файл будет генерироваться заново при каждом обращении (будь то ПС или браузер), поэтому при очень большом количестве страниц данный процесс может быть весьма долгим и трудоемким. В таком случае нужно будет использовать кэш и прочие вещи для уменьшения нагрузки.


Leave a Reply