Sitemap w CakePHP
Informacje na temat pliku z mapą strony można znaleźć na: http://www.sitemaps.org/protocol.php. Jest to zwykły plik XML o określonej strukturze. Tag loc powiadamia googlebota o adresie URL. Dodatkowo można podać lastmod (datę ostatniej modyfikacji), changefreq (jak często strona się zmienia) oraz priorytet, który jest informacją, która strona jest ważniejsza.
Standardowo mapa strony znajduje się w pliku sitemap.xml. Żeby uzyskać taki adres url, można dodać w pliku config/routes.php następującą funkcję:
Router::parseExtensions();
Następnie tworzymy kontroler Sitemap z akcją index i dodajemy w nim komponent RequestHandler oraz helper Xml. Następnie tworzymy widok (views/sitemap/xml/index.ctp).
To wystarczy żeby URL sitemap.xml wywoływał już odpowiednią akcję. RequestHandler spowoduje, że do danej akcji zostanie dołączony layout dla plików XML oraz zamiast zwykłego pliku widoku, użyty będzie ten z katalogu xml odpowiadający danemu widokowi.
W kontrolerze możemy teraz wyciągnąć dane jakie chcemy uzyskać, np. pobrać listę itemek:
$this->set('items', $this->Item->find('all', array('fields' => array('id', 'name'))));
Teraz te dane wystarczy wyświetlić w widoku za pomocą hepera Xml:
$u='';
$changefreq=$xml->elem('changefreq', null, 'daily');
$priority=$xml->elem('priority', null, '1.0');
$loc=$xml->elem('loc', null, 'http://'.$_SERVER["HTTP_HOST"].$this->base);
$xml->elem('url', null, $loc.$changefreq.$priority);
$u.=$xml->elem('url', null, $loc.$changefreq.$priority);
$changefreq=$xml->elem('changefreq', null, 'daily');
$priority=$xml->elem('priority', null, '0.5');
foreach ($items as $d)
{
$loc=$xml->elem('loc', null, 'http://'.$_SERVER["HTTP_HOST"].$this->base.'/items/view/'.$d['Item']['id']));
$xml->elem('url', null, $loc.$changefreq.$priority);
$u.=$xml->elem('url', null, $loc.$changefreq.$priority);
}
echo $xml->elem('urlset', null, $u);
Rozwiązanie takie jest dobre jeśli nie mamy za dużo danych, albo mamy dobry hosting. W przeciwnym wypadku jeżeli mamy np. 30 tysięcy itemek i serwer posiadający tylko 32MB dostępnej pamięci na proces, to niestety dostaniemy błąd informujący o braku pamięci. Rozwiązaniem może być tutaj małe pogwałcenie architektury MVC i pobieranie danych w małych porcjach, np. po 100 itemek i wyświetlanie od razu w kontrolerze odpowiedniego kodu xml. Po zakończeniu można dać exit lub wyrenderować pusty widok. Wygląda to mniej więcej tak:
echo '<?xml version="1.0" encoding="UTF-8" ?>';
?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://<?php echo $_SERVER["HTTP_HOST"].$this->webroot; ?></loc>
<changefreq>daily</changefreq><priority>1.0</priority>
</url><?php
$this->Item->recursive=-1;
$c=$this->Item->find('count');
$count=ceil($c/100)+1;
for($i=1; $i<$count; $i++)
{
$data = $this->Item->find('all', array('fields' => array('id', 'name'), 'limit'=>100, 'page'=>$i));
foreach($data as $d)
{
?>
<url>
<loc>http://<?php echo $_SERVER["HTTP_HOST"].$this->webroot.'items/view/'.$d['Item']['id']); ?></loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
</url>
<?php
}
}
?></urlset><?php
exit();
wtorek, 31 Marzec 2009


Facebook
GoldenLine
LinkedIn