Yii 1.1: How to generate Web feed for an application

10 followers

Web feed is a data format used for providing users with frequently updated content. In this article, we describe how to use Zend_Feed, an excellent component from Zend Framework to generate Web feed for an Yii application. This article can also serve as a general guide on how to use other components in Zend Framework.

To begin with, we download Zend Framework and extract it to the directory protected/vendors/Zend. Verify the file protected/vendors/Zend/Feed.php exists.

Then, in SiteController (or another controller if you like) create a feed action as follows,

Yii::import('application.vendors.*');
require_once('Zend/Feed.php');
 
public function actionFeed()
{
    // retrieve the latest 20 posts
    $posts=Post::model()->findAll(array(
        'order'=>'createTime DESC',
        'limit'=>20,
    ));
    // convert to the format needed by Zend_Feed
    $entries=array();
    foreach($posts as $post)
    {
        $entries[]=array(
            'title'=>$post->title,
            'link'=>$this->createUrl('post/show',array('id'=>$post->id)),
            'description'=>$post->content,
            'lastUpdate'=>$post->createTime,
        );
    }
    // generate and render RSS feed
    $feed=Zend_Feed::importArray(array(
        'title'   => 'My Post Feed',
        'link'    => $this->createUrl(''),
        'charset' => 'UTF-8',
        'entries' => $entries,      
    ), 'rss');
    $feed->send();  
}

To this end, the feed is done and we can access it via the following URL:

http://www.example.com/index.php?r=site/feed

Using the URL management feature of Yii, we can beautify the above URL to something like http://www.example.com/feed.xml.

We can insert this link to the head section of a page using the following code:

Yii::app()->clientScript->registerLinkTag(
    'alternate',
    'application/rss+xml',
    $this->createUrl('site/feed'));

We can also use CHtml::linkTag() to directly insert the link tag at the current place in a page. The difference between these approaches is that the former code can be written anywhere while the latter can only appear in the head section of a view (or layout).

The Zend_Feed component has many other features. If you are interested, please refer to its documentation.

Total 6 comments

#4701 report it
Paul WB at 2011/08/05 06:47am
More Zend classes for <guid>

If you use the guid tag in the item, you need more Zend classes:

Uri/*
Validate/*
Registry.php
#626 report it
Troto at 2010/04/06 06:10pm
How to load the files from Zend framework

For all of you who have trouble loading the Zend framework files here is my solution:

ini_set('include_path', ini_get('include_path').PATH_SEPARATOR.'path/to/zend/framework/'); // without the "Zend" directory and with trailing slash

require_once 'Zend/Loader/Autoloader.php'; Yii::registerAutoloader(array('Zend_Loader_Autoloader','autoload'));

#635 report it
hellodave at 2010/04/03 05:09pm
What worked for me

I didnt really want to upload the whole Zend framework if I didnt need to so I worked out what is required.

3 folders - Feed, Http and Loader
4 files - Exception.php, Feed.php, Loader.php, Uri.php

At least thats what worked for me.
I had to use pretty much all the tweaks in the above comments to get it to work, so thanks all.
For completeness, my controller -

public function actionFeed()
{
    Yii::import('application.vendors.*');
    require_once 'Zend/Loader/Autoloader.php';
    spl_autoload_unregister(array('YiiBase','autoload')); 
    spl_autoload_register(array('Zend_Loader_Autoloader','autoload')); 
    spl_autoload_register(array('YiiBase','autoload'));
    // retrieve the latest 20 posts
    $posts=Post::model()->findAll(array(
        'order'=>'createTime DESC',
        'limit'=>20,
    ));
    // convert to the format needed by Zend_Feed
    $entries=array();
    foreach($posts as $post)
    {
        $entries[]=array(
            'title'=>$post->title,
            'link'=>CHtml::encode($this->createAbsoluteUrl('post/view',array('id'=>$post->id))),
            'description'=>$post->content,
            'lastUpdate'=>$post->createTime,
        );
    }
    // generate and render RSS feed
    $feed=Zend_Feed::importArray(array(
        'title'   => 'dallak',
        'link'    => $this->createUrl(''),
        'charset' => 'UTF-8',
        'entries' => $entries,      
    ), 'rss');
    $feed->send();  
}
#758 report it
schmunk at 2010/03/03 11:15am
Autoload vs. require

Just to note that here:

Instead of

require_once('Zend/Feed.php'); require_once('Zend/Feed/Atom.php');

you may also use:

require_once 'Zend/Loader/Autoloader.php'; spl_autoload_unregister(array('YiiBase','autoload')); spl_autoload_register(array('Zend_Loader_Autoloader','autoload')); spl_autoload_register(array('YiiBase','autoload'));

taken from http://www.yiiframework.com/doc/cookbook/37/

#817 report it
breakeneck at 2010/02/25 05:31am
PHP Error : DOMDocument::createElement(): unterminated entity reference ...

DOMDocument::createElement() that uses ZendFeed cannot pass the unsafe params like a character "&" that was in my url, created due to $this->createUrl('post/show',array('id'=>$post->id)).

So the Solution is in using a htmlentities() before unsafe parameters.

And the correct will be like this:

'link'=>htmlentities($this->createUrl('post/show',array('id'=>$post->id))),

#1575 report it
Alex Muir at 2009/06/18 09:02pm
include error

I followed this guide and received the following error:

PHP Error

Description

include(Zend_Feed_Rss.php) [<a href='function.include'>function.include</a>]: failed to open stream: No such file or directory

Source File

C:\Documents and Settings\Administrator\Desktop\Projects\Businessfeed\Site\yii\framework\YiiBase.php(310)

SOLUTION
Add

require_once('Zend/Feed/Rss.php');
on the line below
require_once('Zend/Feed.php');

Leave a comment

Please to leave your comment.

Write new article
  • Written by: qiang
  • Updated by: Yang He
  • Category: Tutorials
  • Yii Version: 1.1
  • Votes: +4
  • Viewed: 19,207 times
  • Created on: Feb 28, 2009
  • Last updated: Jun 29, 2012