RSS in CakePHP 1.2
We all know what is RSS and how it looks like, here goes simple sample –
<?xml version="1.0"?>
<rss version="2.0">
<channel>
<title>Channel Title</title>
<link>http://www.example.com/</link>
<description>Channel Description</description >
<item>
<title>title1</title>
<link>http://www.example.com/link1</link>
<description>description1</description>
<pubDate> </pubDate>
<guid>http://www.example.com/guid1</guid>
</item>
<item>
<title>title2</title>
<link>http://www.example.com/link2</link>
<description> description2</description>
<pubDate> </pubDate>
<guid>http://www.example.com/guid2</guid>
</item>
<item>
<title>title3</title>
<link>http://www.example.com/link3</link>
<description>description3</description>
<pubDate> </pubDate>
<guid>http://www.example.com/guid3</guid>
</item>
</channel>
</rss>
Creating RSS feed like the above is petty easy with the CakePHP1.2’s RSSHelper. Using the RSSHelper and with the help of the RequestHandler component, we can serve both RSS and (X)HTML content from a single controller action. It is pretty easy to plug in RSS feeds to an already written controller action that serves (X)HTML.
Let’s assume we want to add RSS feeds for the following controller action (PostsController/index) –
function index() {
$this->Post->recursive = 1;
//get all posts
$posts = $this->Post->find(‘all’);
$this->set(‘posts’, $posts);
//set the title
$this->setTitleForLayout(‘All Posts’);
}
Also, assume that $this->Post->find(‘all’) call return an array like the following,
$post[0]['Post']['id'] = 1;
$post[0]['Post']['title'] = 'title1';
$post[0]['Post']['body'] = 'description1';
$data[0]['User']['name'] = 'author1';
$post[0]['Post']['modified'] = '2008-1-1';
$data[1]['Post']['id'] = 2;
$data[1]['Post']['title'] = 'title2';
$data[1]['Post']['body'] = ''description2;
$data[1]['User']['name'] = 'author2';
$data[1]['Post']['modified'] = '2008-1-21';
$data[2]['Post']['id'] = 3;
$data[2]['Post']['title'] = 'title3';
$data[2]['Post']['body'] = ''description3';
$data[2]['User']['name'] = 'author 3';
$data[2]['Post']['modified'] = '2008-1-3';
Now to add RSS feed to this action, first add the ‘RequestHandler’ component in the controller’s $components attribute.
var $components = array('RequestHandler');
And then add the following line in the app/config/routes.php
Router::parseExtensions();
By adding these two lines you are telling Cake to auto-detect the requested content type and respond accordingly. As an example, when a request arrives at www.example.com/posts, Cake will render the corresponding view file and serve the normal XHTML. But if a request arrives at www.example.com/posts.rss, Cake will detect that a RSS feed is requested.
When Cake finds out the requested content type is RSS, it does two things -
1. Automatically adds the RSSHelper to the controller
2. Renders the RSS feed using the view file –app/views/controller_name/rss/action_name.ctp
So, you need to create separate view files for RSS feeds. For the posts/index action, create index.ctp file inside app/views/posts/rss folder with the following codes.
items($posts, 'transformRSS');
function transformRSS($post) {
return array(
'title' => $post ['Post']['title'],
'link' => array('action' => 'view', $post['Post']['id']),
'guid' => array('action' => 'view', $post ['Post']['id']),
'description' => $post ['Post']['body'],
'author' => $post ['User']['name'],
'pubDate' => $post['Post']['modified']
);
}
?>
The items() method can have two parameters.
$rss->items($data, 'callbackFunction');
The first one is an array of data that we want to put in our RSS feed. The second parameter is the name of the callback function that maps each element of the $data array to RSS feed elements. In other words, the callback function is executed for each element of the $data array. Inside the callback function, child elements of the item tag of the RSS feed is mapped against each element of the data array.
Look closely at the above code to have a better understanding of how a callback function maps elements of the $data array to the elements of the RSS.
P.S. The ‘link’ and the ‘guid’ elements take data in regular Cake URL parameter format. Cake automatically reformats the timestamp provided for the “pubDate” element into the RSS standard. The $title_for_layout set in the action will automatically become the RSS feed’s channel title.
If you find your callback function is mostly the same in several different controllers, you can write down a custom helper class with the callback method and (re)use that method in the view file like the following -
echo $rss->items($posts, array($theHelper, 'callbackFunction'));
Sometime instead of using a single controller action for serving both (X)HTML and RSS, you may want to have a separate controller action for serving RSS feed. You can do that too using the RSSHelper! Let’s assume, you want to serve RSS feed from the index() action of the FeedsController.
First, add the RSSHelper in the controller’s $helpers array-
var $helpers = array('rss');
Inside the index() action, define an array of associative arrays for item tags and their child tags, like the following.
$items = array(
array('title' => 'title1', 'guid' => 'http://www.example.com/guid1', 'link' => 'http://www.example.com/link1', 'description' => 'description1'),
array('title' => 'title2', 'guid' => 'http://www.example.com/guid2', 'link' => 'http://www.example.com/link2', 'description' => 'description2'),
array('title' => 'title3', 'guid' => 'http://www.example.com/guid3', 'link' => 'http://www.example.com/link3', 'description' => 'description3')
);
And then pass the array to the view.
$this->set('items', $items);
Define another associative array to denote immediate children of the channel tag and pass that to the view.
$channel = array ('title' => 'Channel Title', 'link' => 'http://www.example.com/', 'description' => 'Channel Description');
$this->set('channel', $channel);
Change the layout of the view to rss,
$this->layout = 'rss/default';
Create the view file – views/feeds/index.ctp, for this action. The view file in fact, will contain only one single line.
items($items); ?>
And now the index() action of the FeedsController is ready to serve RSS feeds.
Sometime, you may like to have customized title, link or description for the channel tag while you are using one single action for serving both (X)HTML and RSS ( usually, they are auto-generated – like title is the same as the page_title set for that action, link is the same as the site address). In that case, you may do something like the following –
if ($this->RequestHandler->isRss()) {
$channel = array (
'title' => 'Channel Title',
'link' => 'http://www.example.com/',
'description' => 'Channel Description'
);
$this->set('channel', $channel);
}
Hope it helps!
About this entry
You’re currently reading “RSS in CakePHP 1.2,” an entry on anupom.toString( );
- Published:
- March 12, 2008 / 12:30 am
- Category:
- Cake, CakePHP, CakePHP 1.2, PHP, RSS
- Tags:
- CakePHP RSS
14 Comments
Jump to comment form | comments rss [?] | trackback uri [?]