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/posts/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.
Search
Recent Posts
- Getting a new Oven, Migrating from CakePHP 1.1 to 1.2
- Code Completion for CakePHP in Eclipse
- CakePHP RC3 released and CakePHP 1.1 new release
- Book Review: CakePHP Application Development
- Providing Contextual Form Help with Mootools
- Creating gracefully degrading javascript and enabling progressive enhancement
- Server up and down time
- Acl Menu Component
- Github hooked up
- Auth and Acl - Automatically updating user Aros
Comments
Saik on 2/9/08
Great stuff, I try to implement it in my side but getting error:
syntax error, unexpected T_STRING in C:\xampp\htdocs\tdb_prod2\app\views\layouts\rss\default.ctp on line 3
its in view file, what all wrong here, and also want to know changes we have to made in controller function.
Cheers
mark story on 2/9/08
Saik: If you are using my layout verbatim with the xsl sheet reference, it is quite probable that you have
short_tagsturned on in your php.ini. If so, you have to echo out all the xml opening<?and?>. Otherwise PHP will interpret them as PHP.Gustavo Carreno 3 weeks, 6 days ago
Hey Mark,
When you mention the view for the action index of the PostsController, shouldn’t the path for such view be app/views/posts/rss/index.ctp and not app/views/rss/index.ctp ?
Cheers,
Gus
mark story 3 weeks, 6 days ago
Gustavo Carreno: You are correct, I’ve corrected it thanks!
Sean 1 week, 1 day ago
Hi Mark,
thanks a lot, this has helped me an awful lot.
Quick question…I’ve used the ‘alternative routing’ like you outlined above. It all works fine, but only when I append .rss to the URL.
Any ideas of what the cause may be?
Thanks a lot.
P.S. Happy Mark Story Day ;)
Pacifists 4 days, 4 hours ago
Thank you for an example, it really helps.
I’m already getting used to the idea, that everything I need Cake HAS :) I have a need for RSS feed and I was like: “Let’s try to enter it into cake API” and it didn’t disappoint me.
Have Something to say?