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.