Jun 22 / Richard Knop

Your own RSS/Atom channel with Zend_Feed

Zend_Feed is mostly used for consuming RSS or Atom feeds from other websites but it is also useful when you want to create your own feeds (I often use it when creating a custom CMS or blog).

Let’s assume you are working on a custom blog script and you need to create an Atom channel of the latest blog posts. The feeds URI will be http://yourdomain.com/feeds (i.e. ‘default’ module, ‘feeds’ controller and ‘index’ action) and blog posts will be located at http://yourdomain.com/index/post/id/n where n is a post id. Here’s the code:

  1. class FeedsController extends Zend_Controller_Action
  2. {
  3.     public function init()
  4.     {
  5.         // set a special layout for feeds
  6.         $this->_helper->layout->setLayout('rss');
  7.     }
  8.  
  9.     public function indexAction()
  10.     {
  11.         // initiate a feeds array with empty array of entries so far
  12.         $feedsArray = array('title' => 'Atom feeds',
  13.                             'link' => $this->view->url(array('module' => 'default',
  14.                                                              'controller' => 'feeds',
  15.                                                              'action' => 'index')),
  16.                             'charset' => 'utf-8',
  17.                             'generator' => 'Zend Framework Zend_Feed',
  18.                             'entries' => array());
  19.  
  20.         // include and initialize Posts.php model and fetch the latest 10 blog posts
  21.         include APPLICATION_PATH . '/modules/default/models/Posts.php';
  22.         $posts = new Posts();
  23.         $posts = $posts->get(10);
  24.  
  25.         // iterate through blog posts and add entries to the $feedsArray
  26.         foreach ($posts as $p) {
  27.             $entry = array(
  28.                      'title' => $this->view->escape($p->title),
  29.                      'link' => $this->view->url(array('module' => 'default',
  30.                                                       'controller' => 'index',
  31.                                                       'action' => 'post',
  32.                                                       'id' => $this->view->escape($p->id)),
  33.                                                 null,
  34.                                                 true),
  35.                      'description' => 'written on '
  36.                                       . date('l \\t\h\e jS, Y',
  37.                                              strtotime($this->view->escape($p->created_at))),
  38.                      'guid' => $this->view->escape($p->id),
  39.                      'content' => $this->view->escape($p->body));
  40.             $feedsArray['entries'][] = $entry;
  41.         }
  42.  
  43.         // send headers for an xml file
  44.         header('Content-type: application/xml');
  45.         // the second argument indicates outputting Atom feeds instead of RSS feeds
  46.         $feed = Zend_Feed::importArray($feedsArray, 'atom');
  47.         // send feeds
  48.         $feed->send();
  49.     }
  50. }

An important thing to remember is that all RSS and Atom feeds must conform to the XML 1.0 specification. For example, you cannot output anything before the <?xml version=”1.0″ encoding=”utf-8″?> tag or else you will get an error (Opera won’t even display webpages when the XML syntax is incorrect). That’s why the layout for the feeds should look like this:

  1. <?php echo $this->layout()->content; ?>

Further reading

Leave a Comment