Building a Custom RSS Feed Using Single Pages, Controllers, and the Page List class.

While the concrete5 page list block provides an RSS feed option, it isn't perfect. Its URL is a little unwieldy, and changes to the page list block may interfere with that RSS feed working. Additionally, I had some filtering requirements for my RSS feed that the page list couldn't quite provide. Those problems are on our radar, but I needed a fix now!

So what did I do? I made a custom single page and controller, at the /feed/ URL. Here are the components:

/controllers/feed.php

<?
 
class FeedController extends Controller {
 
   public function view() {
      Loader::model('page_list');
      header('Content-type: text/xml');
      echo "<?xml version=\"1.0\"?>\n"; ?>
 
   <rss version="2.0">
     <channel>
      <title>andrewembler.com</title>
      <link><?=BASE_URL . DIR_REL?>/feed</link>
      <description>The written words and audio of Andrew Embler, 
      on topics such as concrete5, the web, personal computing, music and art.</description> 
 
   <?
      $pl = new PageList();
      $pl->filterByCollectionTypeHandle('post');
      $pl->sortByPublicDateDescending();
      $posts = $pl->get(10);
      $nav = Loader::helper('navigation');
      foreach($posts as $p) { ?>
 
         <item>
           <title><?=htmlspecialchars($p->getCollectionName());?></title>
           <link><?=BASE_URL . $nav->getLinkToCollection($p)?></link>
           <description>
           <![CDATA[
            <? $a = new Area('Main'); $a->display($p); ?>
            <br/><br/>
            <a href="<?=BASE_URL . $nav->getLinkToCollection($p)?>">Comment on this at andrewembler.com</a>
           ]]>
           </description>
           <pubDate><?=date( 'D, d M Y H:i:s T', strtotime($p->getCollectionDatePublic())) ?></pubDate>
         </item>
      <? } ?>
 
      </channel>
   </rss>
 
   <?
 
      exit;
   }
 
}

As you can see, pretty straightforward. Call the PageList class, filter by post type, setup sorting, and print out RSS XML.

/single_pages/feed.php

This file is empty!

The controller contains the entire logic of the feed generator. The feed.php single page only exists so concrete5 will allow us to create it as a single page, through the dashboard. Simple and easy.