Dynamically load RSS data to Windows Sidebar

<p>Windows Vista as well as Windows 7 offer the possibility to develop so called sidebar gadgets. These pieces of software can be integrated into the desktop sidebar and were designed to offer small chunks of information like the actual weather, the time or calendar dates. Some of the gadgets need the have access to the internet to gain the information required by the service e.g. stock exchange rates. In this case it has to be possible to write gadgets that dynamically load and display the content of a given RSS feed.</p>
1 answer

Use Windows Sidbar Functionality and Ajax

The windows sidebar gadgets are noting more than small HTML files that are added by the OS to the sidebar automatically. The interface between the file and the OS is a XML file that specifies some important facts and looks like this:<code><?xml version="1.0" encoding="utf-8" ?><gadget>  <name>MyGadgetName</name>  <namespace>Namespace.Gadget</namespace>  <version>1.1</version>  <author name="tuwien.ac.at">    <logo src="images/logo.png" />    <info url="http://tuwien.ac.at" />  </author>  <copyright>&#169; Wien, 2009 </copyright>  <description>Newsgadget</description>  <icons>    <icon width="64" height="64" src="images/icon_64.png" />  </icons>  <hosts>    <host name="sidebar">      <base type="HTML" apiVersion="1.0.0" src="main.html" />      <permissions>Full</permissions>      <platform minPlatformVersion="1.0" />      <defaultImage src="images/bg_drag.png"/>    </host>  </hosts></gadget></code> The most important option is the base tag. It specifies the path to the entrypoint - in my example this is the main.html. There are some other options like logos, URLs or version numbers which can be figured out very easily. All that I had to do now was creating the main.html and writing some javascript code to parse the remote RSS feed:<code>function getRSS() {     try     {        var req = null;         if (window.ActiveXObject)        {            req  = new ActiveXObject('Microsoft.XMLHTTP');         }        feedUrl = 'http://mydomain.com/myfeed.rss?'+Math.random();        req.open("GET", feedUrl , true);         req.setRequestHeader("Content-Type", "text/xml");         req.onreadystatechange = function()            {                if(req.readyState == 4)                {                    if(req.status == 200)                    {                        var rssXML = req.responseXML;   // assign the XML file to a var                        if (parseRSS(rssXML) === true) {                            /* YESSSS */                        } else {                            /* UUPS */                            connectionError();                        }                                        }                        else                        {                        alert("Error: returned status code " + req.status + " " + req.statusText);                        connectionError();                    }                }            };        req.send(null);     }    catch(err)    {        alert("General Error: " + err);        connectionError();    }}</code>What this function does is creating a connection to a given rss feed and fetching the data. If that is possible it sends the data to another function named parseRSS() which looks like that:<code>function parseRSS(rssXML) {    var rssItems = rssXML.getElementsByTagName("item");    feedItems =[];    var feedCount=0;    var feedDate;        feedDate = rssXML.getElementsByTagName("dc:date");    if(feedDate[0] !== null) {        feedDate = feedDate[0].firstChild.nodeValue;    } else {        feedDate ="";    }        for(i=0;i<rssItems.length;i++) {        try {                    var title = rssItems[i].getElementsByTagName("title");            var description = rssItems[i].getElementsByTagName("description");            var link = rssItems[i].getElementsByTagName("link");                        if(title[0] !== null && description[0] !== null && link[0] !== null) {                    var feedItem = [];                var relatedItems= [];                    feedItem[0]= title[0].firstChild.nodeValue;                feedItem[1]= description[0].firstChild.nodeValue;                feedItem[2]= link[0].firstChild.nodeValue;                                feedItems[feedCount]= feedItem;                feedCount++;            }                         } catch(err) {}    }    if(feedCount>0) {        return true;    } else {        return false;    }}</code>No I have an associative array named feedItems[] which contains all the fetched RSS data. This information can now be desplayed very easily using basic javascript functionality.Finally I zipped all my files (gadget.xml, main.html, javascript-files, images, etc.) and changed the file suffix from .zip to .gadget. On Windows Vista or Windows 7 system a simple doubleclick on this archive is enough and the gadget will be installed.