Monday, 13 August 2018

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.
  1. class SitemapController extends Zend_Controller_Action
  2. {
  3. public function indexAction()
  4. {
  5. $this->_helper->layout()->disableLayout();
  6. $urls = array(array('loc'=>'http://www.hashbangcode.com/', 'lastmod'=>'2009-04-02T11:34:48+00:00', 'changefreq'=>'daily', 'priority'=>'1.0'));
  7.  
  8. $this->view->urls = $urls;
  9. }
  10. }
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.
  1. partialLoop('sitemap/_urlItem.phtml',$this->urls); ?>
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.
  1. $router = $frontController->getRouter();
  2. $router->addRoute(
  3. 'manageSitemap',
  4. new Zend_Controller_Router_Route('sitemap.xml', array('controller'=>'sitemap','action'=>'index'))
  5. );
Navigating to sitemap.xml now shows me the output of the Sitemap controller.

0 comments:

Post a Comment