Create dynamic RSS feed in Yii

Posted Apr 20, 2014 · Updated May 3, 2014

Edit controllers/SiteController.php and add the following lines:

public function actionRss() {
	$posts=Post::model()->findAll(array(
		'order'=>'create_time DESC',
		'condition'=>'status='.Post::STATUS_PUBLISHED,
		'limit'=>20,
	));

	header('Content-Type: application/xml');
	$this->renderPartial('rss', array('posts'=>$posts));
}

Create views/site/rss.php with the following content:

<?php
$markdown = new CMarkdown;
$doc = new DOMDocument('1.0', 'UTF-8');

$rss = $doc->createElement('rss');
$rss->setAttribute('version', '2.0');
$rss->setAttribute('xmlns:atom', 'http://www.w3.org/2005/Atom');
$rss->setAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
$doc->appendChild($rss);

$channel = $doc->createElement('channel');
$channel->appendChild($doc->createElement('title', CHtml::encode(Yii::app()->name)));
$channel->appendChild($doc->createElement('link', $this->createAbsoluteUrl('/')));
$channel->appendChild($doc->createElement('description', CHtml::encode(Yii::app()->name).'\'s RSS feed.'));
	$atomSelfLink = $doc->createElement('atom:link');
	$atomSelfLink->setAttribute('href', $this->createAbsoluteUrl('site/rss'));
	$atomSelfLink->setAttribute('rel', 'self');
	$atomSelfLink->setAttribute('type', 'application/rss+xml');
$channel->appendChild($atomSelfLink);
$channel->appendChild($doc->createElement('copyright', '&#169;'.date('Y').', '.CHtml::encode(Yii::app()->name)));
$channel->appendChild($doc->createElement('pubDate', date(DATE_RSS)));
$channel->appendChild($doc->createElement('lastBuildDate', date(DATE_RSS, $posts[0]->update_time)));
	$rssImage = $doc->createElement('image');
	$rssImage->appendChild($doc->createElement('title', CHtml::encode(Yii::app()->name)));
	$rssImage->appendChild($doc->createElement('url', $this->createAbsoluteUrl('/static/logo.png')));
	$rssImage->appendChild($doc->createElement('link', $this->createAbsoluteUrl('/')));
	$rssImage->appendChild($doc->createElement('description', CHtml::encode(Yii::app()->name).'\'s website.'));
$channel->appendChild($rssImage);
$rss->appendChild($channel);

foreach($posts as $post) {
	$item = $doc->createElement('item');
	$item->appendChild($doc->createElement('title', $post->title));
	$item->appendChild($doc->createElement('link', $this->createAbsoluteUrl('post/view', array('id'=>$post->id, 'title'=>$post->title))));
		$description = $doc->createElement('description');
		$description->appendChild($doc->createCDATASection($markdown->transform($post->content)));
	$item->appendChild($description);
	$item->appendChild($doc->createElement('dc:creator', ucfirst($post->author->username)));
	$item->appendChild($doc->createElement('category', CHtml::encode($post->tags)));
		$guid = $doc->createElement('guid', $post->id);
		$guid->setAttribute('isPermaLink', 'false');
	$item->appendChild($guid);
	$item->appendChild($doc->createElement('pubDate', date(DATE_RSS, $post->create_time)));
	$channel->appendChild($item);
}

echo $doc->saveXML();

To make it easy for people to subscribe to your new RSS feed you can add this to the head section of views/layouts/main.php of your theme:

<?php Yii::app()->clientScript->registerLinkTag('alternate', 'application/rss+xml', $this->createAbsoluteUrl('site/rss')); ?>

Leave a Comment

This will never be published.
You may use Markdown Syntax. HTML is not allowed.