Creating RSS feeds with CakePHP and extensionless routing
Mar 28 2008
Making RSS feeds and alternative content types other than HTML opens a lot of options in how your content can be used, displayed and combined. In prior version of cakePHP webservices were indicated by prefixing a url with the desired content type so an xml version of a blog index might look like xml/posts/index. This has gone the way of the pterodactyl and been replaced with a more easy to use extension based system in 1.2. If you wanted to get an xml version of posts/index in cakePHP 1.2 you can simply append the desired extension .rss making your URL posts/index.rss. Before we jump to far ahead trying to get our webservice up and running we need to do a few things. First parseExtensions needs to be activated, this is done in app/config/routes.php
- Router::parseExtensions('rss');
-
Secondly its a good idea to add RequestHandler to you $components array. This will allow a lot of cake automagic to occur. In the call above I’ve activated the .rss extension. When using Router::parseExtensions() you can pass as many arguments or extensions as you want. This will activate each extension/content-type for use in your application. Now when the address posts/index.rss is requested you will get an xml version of your posts/index. However, first we need to make the view files that will create our rss/xml feed.
The View of RSS
Before we can make an RSS version of our posts/index we need to get a few things in order. First we need to create an rss layout. We’ll put that file in app/view/layouts/rss and call it default.ctp.
Mine looks like this
Show Plain Text
- <?xml-stylesheet type="text/xsl" href="<?php echo $rss->webroot('css/feed.xsl') ?>" ?>
- <?php
-
- ?>
Update: Thought I would show what normally goes into a channel element as well.
Show Plain Text
- 'link' => '/posts/rss',
- 'url' => '/posts/rss',
- 'description' => 'Recent writing and musings of Mark Story',
- 'language' => 'en-us',
- 'managing-editor' => 'no-spam@my-domain.com',
- );
You might have noticed a reference to a feed.xsl checkback for more on that. This is a basic layout that accepts a set of fairly self explanatory variables. Next up is the actual view for posts/index. Again we need a separate view file so create app/views/rss/index.ctp my file ended up looking like this.
- <?php
- /**
- * Callback used by RssHelper::items()
- */
- function rss_transform($item) {
- 'link' => '/posts/view/'.$item['Post']['slug'],
- 'guid' => '/posts/view/'.$item['Post']['slug'],
- 'pubDate' => $item['Post']['created'],
- );
- }
-
- $this->set('items', $rss->items($posts, 'rss_transform'));
- ?>
Now we never added the RssHelper to the $helpers array nor do we have to. Since we are using the RequestHandler component, whenever an extension based request is made, the proper helper if available is automatically available for use in your views. So there you have it. A simple quick and easy way to create an RSS feed out of anything really.
Alternative Routing
Currently you can get to the new feed at /posts/index.rss. But what if we want a different url, because we just want to or we are dealing with integrating to an existing URL structure or legacy site. For example we want to use /posts/feed for our newly baked rss feed. We can set up a route like this.
- 'action' => 'index',
- ) );
The feed is now accessible at /posts/feed I hope you’ve found this helpful, if you have any problems post a comment and I do the best I can to answer your questions.
Update: after reading the RssHelper source a bit better there is a cleaner way to do what I had done above. I’ve changed the code sample to reflect the updates.
Recent Posts
- Creating easy reports with pivot tables
- Auth and ACL an end to end tutorial pt.2
- Auth and ACL an end to end tutorial pt. 1
- Introducing the Webservice Behavior
- More dogfood
- Eating my own dogfood Upgrading to CakePHP RC1
- CakePHP RC1 released
- PHP's isset() and arrays
- Contributing to your first open source project.
- Hacking the CakePHP FormHelper Adding Required Indicators
Comments
There are no Comments, Be the First!
Have Something to say?