Using mod_rewrite And Zend Framework To Display Dynamic sitemap.xml


Whilst creating a site the other day I thought about how I would manage the sitemap.xml file. This file is basically a XML file containing a list of URLs. Most major search engines understand (and look for) this file, so having it present on a site is a definite must.

I have been down the route before of having a sitemap.xml file created by the application every time a new record or something was added, but as this was a high traffic, multi-user site this approach just had to many problems. The main problem (aside from the potential performance hit) was that I would have to spend hours tying the calls to the sitemap.xml creation file into my application.

I then hit upon the idea of using a RewriteRule that would mask a controller as the sitemap.xml file. This would mean that the sitemap.xml controls could be kept away from all other parts of the application (so I could use the same template again), but I could also use Zend_Cache to cache the sitemap.xml file daily and therefore save on processing time.

First I needed to create a RewriteRule that would redirect a call to sitemap.xml to the Sitemap controller.

RewriteRule ^(.*)sitemap.xml$ /sitemap/index [L]

Next I created the Sitemap controller and made sure that the index action did not show the layout. The URLs are passed as an array to the view.

class SitemapController extends Zend_Controller_Action
{
public function indexAction()
{
$this->_helper->layout()->disableLayout();
$urls = array(array('loc'=>'http://www.talkincode.com/', 'lastmod'=>'2009-04-02T11:34:48+00:00', 'changefreq'=>'daily', 'priority'=>'1.0'));

$this->view->urls = $urls;
}
}

In order for the Sitemap controller to display anything it needs to have a view to render. This creates the basic outline of the file and uses the partialLoop() function to print out the array of URLs.

<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<?php echo $this->partialLoop('sitemap/_urlItem.phtml',$this->urls); ?>
</urlset>

Here is the file _urlItem.phtml, which gets rendered for every item in the $this->urls array.

<url>
<loc><?php echo $this->loc; ?></loc>
<lastmod><?php echo $this->lastmod; ?></lastmod>
<changefreq><?php echo $this->changefreq; ?></changefreq>
<priority><?php echo $this->priority; ?></priority>
</url>

I assumed that everything would be working nicely now, but when I went to a browser and tried to find sitemap.xml I was presented with a message that said sitemap.xml was an invalid controller.

Just to test I added a redirect to the end of the RewriteRule to make sure that the rule worked.

RewriteRule ^(.*)sitemap.xml$ /sitemap/index [R=301, L]

This redirected to the correct place, so it must have been Zend Framework that was causing the error to occur. After a bit of thinking I realised that I could create a route that would reroute the call to the missing sitemap.xml controller to the existing Sitemap controller. Here is the rule I created, just add this to your bootstrap file.

$router = $frontController->getRouter();
$router->addRoute(
'manageSitemap',
new Zend_Controller_Router_Route('sitemap.xml', array('controller'=>'sitemap','action'=>'index'))
);

Navigating to sitemap.xml now shows me the output of the Sitemap controller.

As talkincode.com

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s