How to widgetize a RSS feed?

a.k.a, “How to turn a RSS feed into a UWA widget”.

One of the primary use of a widget it to provide users with an easy access to your data. Many websites rely on RSS in order to provide their data. If this is your case, it is in your best interest to provide your own widgetization of your RSS feed. This is how you do it.

This is a simplified version the RSSReader examples, which you can already add to your Netvibes.

First step

We advise you to start with our sample UWA skeleton. It contains all the starting code you will need, upon which you can build your own code and content. Then, you can test and dissect our existing UWA examples.

Remember: to use the proper UWA template, your feed MUST be displayed in a HTML list (ul/li), where the ul element MUST use the nv-feedList CSS class.

Building the preferences

When building your widget, the first rule to abide is to fill-in the correct metadata. Their purpose is to describe the widget itself. Read about them in ”Content of the XHTML file”.

You have first to define what will be the preference available to the use. Each of them must have its own preference tag. For the purpose of our simple RSS Reader, we will have two preferences: the feed URL, and the number of displayed items.

<widget:preferences>
  <preference name="url" type="text" label="URL" 
    defaultValue="http://feeds.feedburner.com/NetvibesDevBlog" />
  <preference name="limit" type="range" label="Number of items to display" 
    defaultValue="10" step="1" min="1" max="25" />
</widget:preferences>

If you don't want your users to change the URL, you only have to change the first preference tag's type to hidden: the preference will still exist, but will not be avalaible to the users.

Scripting it all

The gist of your widget resides in your JavaScript code. It has to download the feed residing at the URL (set by the user in the preference tag) as soon as the widget is loaded, parse the obtained JSON representation of the feed, and retrieve the needed data from it, then display as many items as the appropriate preference tag specifies.

The downloaded feed will be stored in a local feed variable. We set it to false at first, waiting to be filled in by the UWA.Data.getFeed() method.

The display method will simply be called display, and will take feed as its only argument.

All the informatin about using JavaScript and the DOM is available in the ”Using JavaScript and Ajax in a UWA widget” section.

var BasicRSSReader = {}
 
BasicRSSReader.feed = false;
 
BasicRSSReader.display = function(feed) {
  // display code
}

The display will be called at launch time, and everytime the URL preference is updated. Both are handled by the widget.onLoad() method, from the widget object. That object, specific to UWA, is described in this section.

widget.onLoad = function() {
  UWA.Data.getFeed(widget.getValue('url'), BasicRSSReader.display);   
}

The widget.getValue() method is charge of getting the content of the URL preference tag. UWA.Data.getFeed() gets the feed located at the URL, builds a JSON representation of it, then sends it to the widget's display() method.

display() is then in charge of dealing with the rest of the widget: get the number of items to display, and loop through the items list. Each displayed item has to generate its own markup, using JavaScript methods.

Here is how it's done:

BasicRSSReader.display = function(feed) {
  if (feed) BasicRSSReader.feed = feed;
 
  // get the number of items to display
  widget.preferences[1].max = BasicRSSReader.feed.items.length;
 
  // create the 'ul' element, applying it the CSS class 'nv-feedList'  
  var feedList = widget.createElement('ul');
 
  // your 'ul' element MUST make use of the 'nv-feedList' class
  // to ensure your widget uses the UWA UI library
  feedList.className = 'nv-feedList';
 
  // number of parsed items
  var j = 0;
 
  // loop through the downloaded items
  for(var i=0; i < BasicRSSReader.feed.items.length; i++) {
    // if the limit is reached, stop looping
    if (j >= widget.getValue('limit')) break;
 
    // for each item, create the 'li' element
    var item = BasicRSSReader.feed.items[i];
    var li = widget.createElement('li');
 
    // create and fill the 'a' element of the item with the item's link
    var a = widget.createElement('a');
    a.href = item.link;
 
    // fill the 'a' element with the item's title
    var displayTitle = item.title;
    a.innerHTML = displayTitle;
 
    // build the title from the 255 first characters of the content
    // remove the content's HTML tags along the way
    var title = item.content.stripTags().truncate(255);
    a.title = title;
 
    // set a tooltip on the 'a' element, with the item's content
    a.onmouseover = function() {
      UWA.Utils.setTooltip(this, this.content, 250);
    }
 
    // finally append the 'a' element we just filled, into the 'li' element
    li.appendChild(a);
 
    // ...and append the 'li' element to the main 'ul' element        
    feedList.appendChild(li); 
    j++;
  }
 
  // once the needed items have been parsed,
  // send the main 'ul' element to the HTML body tag
  widget.setBody(feedList);
}

Using a set list of URLs rather than URL textfield

The reader presented here only works for one feed at a time, which you have to fill by hand if you want to target a new feed. Through the list preference tag, you can provide the user with a list of URLs.

Read about the list preference here.

Here is an example code:

<widget:preferences>
  <preference name="url" type="list" label="URL"
  defaultValue="http://example.com/feed1" >
    <option label="Feed 1" value="http://example.com/feed1" />
    <option label="Feed 2" value="http://example.com/feed2" /> 
    <option label="Feed 3" value="http://example.com/feed3" />
  </preference>
  <preference name="limit" type="range" label="Number of items to display" 
    defaultValue="10" step="1" min="1" max="25" />
  <preference name="search" type="hidden" defaultValue="" />
</widget:preferences>

Please note that you must provide a defaultValue - using selected=“selected” will not work.