Feed Writer Generator Extension to create your feeds. Currently supports RSS 1.0, RSS 2.0 and ATOM 1.0.
IMPORTANT I have updated the github repo so it is now isolated to update independently from other extensions. Get the most up to date version from its github repository.Requirements ¶
- Developed using Yii version 1.1.5
Usage ¶
Unzip the contents of the package and place it on your protected/extensions folder.
Examples of use
RSS 1.0
Yii::import('ext.feed.*');
// specify feed type
$feed = new EFeed(EFeed::RSS1);
$feed->title = 'Testing the RSS 1 EFeed class';
$feed->link = 'http://www.ramirezcobos.com';
$feed->description = 'This is test of creating a RSS 1.0 feed by Universal Feed Writer';
$feed->RSS1ChannelAbout = 'http://www.ramirezcobos.com/about';
// create our item
$item = $feed->createNewItem();
$item->title = 'The first feed';
$item->link = 'http://www.yiiframework.com';
$item->date = time();
$item->description = 'Amaz-ii-ng <b>Yii Framework</b>';
$item->addTag('dc:subject', 'Subject Testing');
$feed->addItem($item);
$feed->generateFeed();
RSS 2.0
Yii::import('ext.feed.*');
// RSS 2.0 is the default type
$feed = new EFeed();
$feed->title= 'Testing RSS 2.0 EFeed class';
$feed->description = 'This is test of creating a RSS 2.0 Feed';
$feed->setImage('Testing RSS 2.0 EFeed class','http://www.ramirezcobos.com/rss',
'http://www.yiiframework.com/forum/uploads/profile/photo-7106.jpg');
$feed->addChannelTag('language', 'en-us');
$feed->addChannelTag('pubDate', date(DATE_RSS, time()));
$feed->addChannelTag('link', 'http://www.ramirezcobos.com/rss' );
// * self reference
$feed->addChannelTag('atom:link','http://www.ramirezcobos.com/rss/');
$item = $feed->createNewItem();
$item->title = "first Feed";
$item->link = "http://www.yahoo.com";
$item->date = time();
$item->description = 'This is test of adding CDATA Encoded description <b>EFeed Extension</b>';
// this is just a test!!
$item->setEncloser('http://www.tester.com', '1283629', 'audio/mpeg');
$item->addTag('author', 'thisisnot@myemail.com (Antonio Ramirez)');
$item->addTag('guid', 'http://www.ramirezcobos.com/',array('isPermaLink'=>'true'));
$feed->addItem($item);
$feed->generateFeed();
Yii::app()->end();
ATOM 1.0
Yii::import('ext.feed.*');
$feed = new EFeed(EFeed::ATOM);
// IMPORTANT : No need to add id for feed or channel. It will be automatically created from link.
$feed->title = 'Testing the ATOM RSS EFeed class';
$feed->link = 'http://www.ramirezcobos.com';
$feed->addChannelTag('updated', date(DATE_ATOM, time()));
$feed->addChannelTag('author', array('name'=>'Antonio Ramirez Cobos'));
$item = $feed->createNewItem();
$item->title = 'The first Feed';
$item->link = 'http://www.ramirezcobos.com';
// we can also insert well formatted date strings
$item->date ='2010/24/12';
$item->description = 'Test of CDATA Encoded description <b>EFeed Extension</b>';
$feed->addItem($item);
$feed->generateFeed();
Change Log ¶
- v.1.3 Added stylesheet support
- v.1.2 Added support for atom:link
- v.1.1 Fixed bug on EFeedItemAtom thanks to Flokey82
Resources ¶
web development has never been so fun
www.2amigos.us - under construction -
Thanks for sharing
Looks great, I'll be definitively using it soon and then I'll give you my feedback
Small and simple
Thank you! Very easy to use, and doesn't have to include parts of other frameworks to use! ;)
@Sarke & @gusnips
Any feedback to create a better extension always welcome. I would love to make this RSS feed much more universal (iTunes for example?)
ITunes
@tonydspaniard: Thanks! Looks like an awesome extension.
Please keep us posted with your progress with making your extension more universal.
We will need to use itunes specific tags.
Love It
This extension was very easy to get running, and quite effective. Thank you for sharing it.
Nice, class but could use some improvments.
I need MRSS (Media RSS) support so I tried to extend your class to add the necessary second xmlns, but I found $type and renderHead() private rather than protected preventing this.
You should change your private classes, when appropriate, protected to make it more extensible.
Even better, for my particular needs, would have been for renderHead() to either get the header from the appropriate EFeedItem class (not sure how you would structure that well) or to build it's data from a modifiable associative array.
I would also be nice to have it behave like classes such as CGridView where a dataProvider can be passed to it along with a list of column names and the items auto populated from that.
@cstdenis
Great suggestion!
I am in the middle of adding MRSS and iTunes support to the extension. Unfortunately I am very busy at the moment.
I will consider the dataProvider recommendation aswel. Very good feedback, thanks.
Great extension, only one suggestion
Having a return rss content option would be nice. Like this:
This is useful for those who may want to cache
/** * * Generates the Feed */ public function generateFeed($return=false) { if (!$return) { header("Content-type: text/xml"); } $returnString = $this->renderHead($return); $returnString .= $this->renderChannels($return); $returnString .= $this->renderItems($return); $returnString .= $this->renderBottom($return); if ($return) { return $returnString; } } /** * * Prints the xml and rss namespace * */ private function renderHead($return=false) { $content = '<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL; if(!empty($this->stylesheets)) $content .= implode (PHP_EOL, $this->stylesheets); if($this->type == self::RSS2) { $content .= CHtml::openTag('rss',array( "version"=>"2.0", "xmlns:content"=>"http://purl.org/rss/1.0/modules/content/", "xmlns:wfw"=>"http://wellformedweb.org/CommentAPI/")).PHP_EOL; } elseif($this->type == self::RSS1) { $content .= CHtml::openTag('rdf:RDF',array( "xmlns:rdf"=>"http://www.w3.org/1999/02/22-rdf-syntax-ns#", "xmlns"=>"http://purl.org/rss/1.0/", "xmlns:dc"=>"http://purl.org/dc/elements/1.1/" )).PHP_EOL; } else if($this->type == self::ATOM) { $content .= CHtml::openTag('feed', array("xmlns"=>"http://www.w3.org/2005/Atom")).PHP_EOL; } if ($return) { return $content; } else { echo $content; } } /** * * Prints the xml closing tags * */ private function renderBottom($return=false) { $content = ''; if($this->type == self::RSS2) { $content .= CHtml::closeTag('channel'); $content .= CHtml::closeTag('rss'); } elseif($this->type == self::RSS1) { $content .= CHtml::closeTag('rdf:RDF'); } else if($this->type == self::ATOM) { $content .= CHtml::closeTag('feed'); } if ($return) { return $content; } else { echo $content; } } /** * * Prints the channels of the xml document * @throws CException */ private function renderChannels($return=false) { $content = ''; switch ($this->type) { case self::RSS2: $content .= '<channel>' . PHP_EOL; break; case self::RSS1: if(null !== $this->RSS1ChannelAbout ) $content .= CHtml::tag('channel',array('rdf:about'=>$this->RSS1ChannelAbout )); else $content .= CHtml::tag('channel',array('rdf:about'=>$this->link)); break; } // Printing channel items foreach ($this->feedElements->itemAt('channels') as $key => $value) { if($this->type == self::ATOM && $key == 'link') { // ATOM prints link element as href attribute $content .= $this->makeNode($key,'',array('href'=>$value)); // And add the id for ATOM $content .= $this->makeNode('id',$this->uuid($value,'urn:uuid:')); } else { $content .= $this->makeNode($key, $value); } } // RSS 1.0 have special tag <rdf:Seq> with channel if($this->type == self::RSS1) { if( null === $this->feedElements->itemAt('items') ) throw new CException( Yii::t('EFeed', 'No items have been set') ); $content .= "<items>" . PHP_EOL . "<rdf:Seq>" . PHP_EOL; foreach ($this->feedElements->itemAt('items') as $item) { $tag = $item->link; if(null === $tag ) throw new CException( Yii::t('EFeed', 'For RSS 1.0 specifications link element should be add per item') ); $content .= CHtml::tag('rdf:li',array('resource'=>$tag->content ),true).PHP_EOL; } $content .= "</rdf:Seq>" . PHP_EOL . "</items>" . PHP_EOL; } if ($return) { return $content; } else { echo $content; } } /** * * Prints feed items * @throws CException */ private function renderItems($return=false) { if(null === $this->feedElements->itemAt('items')) throw new CException( Yii::t('EFeed', 'No feed items configured') ); $content = ''; foreach ($this->feedElements->itemAt('items') as $item) $content .= $item->getNode(); if ($return) { return $content; } else { echo $content; } }
RSS1: tag CHANNEL must be open
$feed = new EFeed(EFeed::RSS1); foreach ($news as $news_item) { $item = $feed->createNewItem(); $item->title = $news_item->title; ... $feed->addItem($item); } $feed->generateFeed();
This code generate next:
<rdf:RDF xmlns:rdf="" xmlns="" xmlns:dc=""> <channel rdf:about=""/> <title></title> <link></link> <description> </description> <ChannelAbout></ChannelAbout> <items> ...
Why tag channel rdf:about=""/> is closed? "/>" Fix this bug!
@chuvbiz
I'll do it on my free time, thanks for pointing that out, but there are ways to tell people what to do or not, don't you think?
Moreover, there is a GitHub project where YOU can support the extension and help the community with the change.
Multiple media:thumbnail tags
Hello,
EFeed is a nice extension which allows a simple interface for producing an RSS or mRSS feed. Its worked well for my company's app thus far. Thanks for providing EFeed to the Yii community.
Recently, we've decided we want to include the full inventory of thumbnails for an image gallery for a single item. I need to include multiple %media:thumbnail url=''% tags. I seem to be unable to do this, as the inherited functionality for EFeedItemAbstract::addTag() effectively overwrites any existing tag.
I am aware that alternatively, I can create a separate images feed which contains one item per media:content, to use to render a feed of all images. This is not an ideal setup for our syndication.
Is there a way I can add multiple %media:thumbnail% tags to an item with the latest version of EFeed?
Thanks!
thank you
but cannot add image and ico to feed
Re: Multiple media:thumbnail tags
Thanks for responding, but would you care to elaborate? The Yahoo mRSS standard states that it is perfectly valid to use multiple %media:thumbnail% tags per item. Im wondering why this extension overlooks this issue.
Thanks
While I don't have an answer for Stratigos question, it made me realize that I should spend a few words and send my thanks for this extension.
I'm just a random individual who have set up a Yii site, but just as I like to get feedback on free work, I'm sure you like that too. So thanks for the extension which for me have worked very well.
Another limitation?
In addition to my previous question which has not been answered since July, I have another question which may be a limitation of EFeed.
Im trying to create a child node of an existing item node. Id like for it to have its own text node, as well as attributes. I dont seem to have this option with EFeed, or perhaps I am using it wrong.
Id like a structure as follows:
<item> ...other nodes... <media:content attribute1='value1' attribute2='value2'> <media:description attribute1a='value1a'>DESCRIPTION TEXT</media:description> </media:content> </item>
If I create this via:
$innerTags = array( 'media:description' => array('attribute1a' => 'value1a'); ); $item->addTag('media:content', $innerTags, array( 'attribute1' => 'value1', 'attribute2' => 'value2', ));
I cant seem to add any content to the %media:description% tag, no matter how I manipulate how that variable is assigned (arrays within arrays, explicitly naming an array cell 'content', appending an array to the array passed into the addTag() call...), I am unable to make it a non-self closing tag with some text in its text node. Ive tried creating a new EFeedTag object, which results in object-convert-to-string exceptions.
Am I doing something wrong? How can I make a non self-closing tag with attributes a child of an existing non self-closing tag?
All in all I think PHP's DOMDocument class is a much more reliable means of creating feeds than EFeed for these reasons. Can we expect an update, or at least a logical response, anytime soon?
@Stratigos
Big apologies for the time not answering the requests. Nowadays, I am truly, very busy and unable to support as much as I would love to, to all extensions that I have created.
That is the reason why I published all my extensions to GitHub so to be able to collaborate with all of you and make them better whilst at the same being able to continue with my work-responsibilities.
Nevertheless, I made a mistake by publishing all my work in one piece, so I am willing to publish them one by one to a single repository respectively.
Would be great that if any of you have suggestions, issues and or improvements to add to it, could help me at github...
I will try to get back asap, but I am too busy, seriously.
Thanks for your understanding...
@Stratigos
Seems that EFeed needs refactoring, I didn't include attributes for the heads of the media type required:
// Example rss 2 header <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
As you can see on https://github.com/tonydspaniard/Yii-extensions/blob/master/extensions/EFeed/EFeed.php#L310 the extension doesn't support that yet. But it won't be too hard to add that ability to provide media types for the feed.
Hope I have time soon to do it.
About your second limitation:
Arrays are not supported on the 'content', you could just create the tags and pass them through:
$innerTag = CHtml::tag('media:description',array('attribute1a' => 'value1a')); $item->addTag('media:content', $innerTag, array( 'attribute1' => 'value1', 'attribute2' => 'value2', ));
Namespace prefix atom on link is not defined
I get an error using chrome due to this line.
$feed->addChannelTag('atom:link','http://estorefeedback.com/rss/'.$url_rewrite );
Namespace prefix atom on link is not defined
I am using feed.v1.3.zip with the latest YII release as of about 3 months ago.
Any thoughts?
sidestepped...
@Antonio
That doesnt answer the question. The issue is that there isnt a way to have multiple tags of the same name as children of some parent tag/element (or actually, multiple tags of the same name at all).
For example, Im unable to do this:
Or this:
So im basically putting this out there for anyone in the same position - if you need to publish to a partner with specific needs that require multiple elements of the same name per item element, EFeed wont work, and I havent arrived at an elegant way to extend EFeed to get around it (issue is up in Yii framework classes employed).
@Stratigos
You are right,
Would be nice to have some proposals at github
Secure feeds
I faced the problem with secure feeds (using https). The error during feed generation was "{link} does not seem to be a valid URL".
It turned out the regex used to validate url didn't take into account https (class EFeedItemAbstract, function setLink, line 110):
$validator->pattern = '/(((f|ht){1}tp:\/\/)[-a-zA-Z0-9@:%_\+.~#?&\/\/=]+)/i';
I fixed it by modifying this line as follows:
$validator->pattern = '/(((f|ht){1}tps?:\/\/)[-a-zA-Z0-9@:%_\+.~#?&\/\/=]+)/i';
Re: Namespace prefix atom on link is not defined
@Brian Nettles
> Namespace prefix atom on link is not defined
> I am using feed.v1.3.zip with the latest YII release as of about 3 months ago.
You can downgrade the extension to the version 1.2 without this bug
@BorisK
Had the same error - it seems like EFeed.php line 314 should be replaced to
"xmlns:atom"=>"http://www.w3.org/2005/Atom",
it worked for me
...
Oh, I've spent too much time trying to validate the REAL rss. THought it would be much easier :( My main problem by now is:
line 14, column 11: atom:link should not have text (all data is in attributes) [help] <atom:link>http://localhost.com</atom:link>
so I wondering how can I do some workaround using internal methods of EFeed?
I have hardcoded into EFeed this element by now:
echo "<atom:link href=\"http://site.com/rss.php\" rel=\"self\" type=\"application/rss+xml\" />";
No feed items configured /protected/extensions/feed/EFeed.php 847
Here is my code
// RSS 2.0 is the default type $feed = new EFeed(); $feed->title= 'blah blah'; $feed->description = 'blah blah'; $feed->addChannelTag('language', 'en-us'); $feed->addChannelTag('pubDate', date(DATE_RSS, time())); $feed->addChannelTag('link', 'http://baabaa.com' ); $jobs = Job::model()->findAll($criteria); foreach($jobs as $job) { if (empty($job)) continue; $item = $feed->createNewItem(); $item->title = utf8_encode($job->job_title); $item->link = Yii::app()->createAbsoluteUrl('job/view',array( 'id'=>$job->id)); $item->date = time(); $item->description = utf8_encode(GFunctions::truncate($job->description, 500) . '...'); $feed->addItem($item); } $feed->generateFeed(); Yii::app()->end();
I keep getting Exception: No feed items configured /protected/extensions/feed/EFeed.php 847, and I can not figure out what was wrong.
Please Help
Way better approach
I write this comment long after I tried to use efeed - too much errors and poblems with extension. I found IMHO MUCH elegant and flexible soltion proposed it this post:
http://yiiframework.ru/forum/viewtopic.php?f=9&t=16#p88
I've implemented 100% working solution very quickly.
For those who don't understand Russian, it's all about separate rss-controller, view and layout.
Problem with efeed in chrome browser
I did as suggested above, getting following errors..
Thing is that everything is fine in Mozilla Firefox browser, getting following error in Chrome
This page contains the following errors:
error on line 14 at column 11: Namespace prefix atom on link is not defined
Below is a rendering of the page up to the first error.
Problem with efeed in chrome browser
I did as suggested above, getting following errors..
Thing is that everything is fine in Mozilla Firefox browser, getting following error in Chrome
This page contains the following errors:
error on line 14 at column 11: Namespace prefix atom on link is not defined.
plz help me
Re: Problem with efeed in chrome browser
Try to fix extensions/feed/EFeed.php->renderChannels() with elseif:
if($this->type == self::ATOM && $key == 'link') { // ATOM prints link element as href attribute echo $this->makeNode($key,'',array('href'=>$value)); // And add the id for ATOM echo $this->makeNode('id',$this->uuid($value,'urn:uuid:')); } elseif ($this->type == self::RSS2 && $key == 'atom:link') { echo $this->makeNode($key,'',array('rel'=>'self', 'href'=>$value, 'type'=>'application/rss+xml')); } else { echo $this->makeNode($key, $value); }
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.