Using the Web Services Proxy
So you have a RSS feed from your blog or someone else’s blog and you want to turn that into a widget? Well, with Widgetbox it’s pretty simple… we provide the tools you’ll need to get started and all you need to do is add a little creativity!
The basic concept of the RSS XML widget is to retrieve some XML data from a RSS feed, iterate through the items of the feed, and render some HTML content. So before we begin, make sure you have at least a little understanding of how web pages are created, what RSS and XML are, and know a little bit of JavaScript. You don’t need to be an expert and you can always just cut and paste the provided code into your widget.
To register new widgets in Widgetbox, click the My Widgets tab and click on the Registered link on the left (if you have never registered a widget before, click on the Submit a Widget button instead). Click the button, Register a New Widget, to start the widget registration wizard. On the first tab you’ll want to choose a new “Hosted Widget”. This means you will define the actual HTML (including any scripts and CSS) for your widgets. First, enter a cool name for your widget. Next, select Script Library from the HTML select list. Of the choices that appear to the right, select Proxy Request and click Insert. A piece of JavaScript will be inserted into the body of your widget source. This piece of code will go out to the web and get the XML data from a RSS feed that you specifiy. For demonstration purposes, I’ll use the Yahoo Odd News RSS feed:
Code:
req.open("get", "http://rss.news.yahoo.com/imgrss/1600");
We will need to know the structure of the XML in order to parse it correctly. To see what the XML data looks like, simply open up this URL in a browser. Now that I have some data, I can simply loop over all of the items and display them as a list of links like so:
Code:
var resXML = req.responseXML;
var contentStr = "<ul>";
var items = resXML.getElementsByTagName("item");
// loop over all the articles...
for (var i = 0; i < items.length; i++) {
var resXML = req.responseXML;
var items = resXML.getElementsByTagName("item");
var itemNodes = items[i].childNodes;
var articleTitle = "";
var articleURL = "";
// parse the XML for the pieces of data we want...
for (var j=0; j < itemNodes.length; j++) {
var itemNode = itemNodes[j];
if ("title" == itemNode.tagName) {
articleTitle = (itemNode.firstChild.nodeValue) ? itemNode.firstChild.nodeValue : itemNode.textContent;
} else if ("link" == itemNode.tagName) {
articleURL = (itemNode.firstChild.nodeValue) ? itemNode.firstChild.nodeValue : itemNode.textContent;
}
}
// build up the HTML string...
contentStr += "<li><a href=\"" + articleURL + "\" target=\"_new\">" + articleTitle + "</a></li>";
}
contentStr += "</ul>";
// do something with the contentStr
Notice that tags I want to loop over are the <item> tags, these elements contain the article data. For each article, I extract the <title> and the <link> tags. I use these two pieces of data to build a HTML string and assign it to the contentStr variable. After iterating through all the items, I can do whatever I want with the HTML string. For example, if I want to insert my unordered list <ul> into a <div> in the widget body, I could add this line to the end:
Code:
document.getElementById("content-div").innerHTML = contentStr;
Then, below the the ending </script> tag, I could have:
Code:
<div id="content-div"><!-- the content string should be inserted here --></div>
But that's just the beginning! Say I wanted to get fancy and style it with CSS and throw a thumbnail image in there as well. Well, following in the flavor of television cooking shows, here is the finished, pre-baked code:
Code:
<script type="text/javascript">
//<![CDATA[
var req = new WIDGETBOX.net.ProxiedHTTPRequest();
req.onload = function() {
var resXML = req.responseXML; // this is the XML document object
var contentStr = ""; // use this string to store the generated HTML
var items = resXML.getElementsByTagName("item"); // gets all "item" elements
var yahooImgNode = resXML.getElementsByTagName("url")[0];
var yahooImageValue = (yahooImgNode.firstChild.nodeValue) ? yahooImgNode.firstChild.nodeValue : yahooImgNode.textContent;
var imageStr = "<img src=\"" + yahooImageValue + "\" border=\"0\" />";
document.getElementById("articles-header").innerHTML = imageStr;
for (var i = 0; i < items.length; i++) {
var resXML = req.responseXML;
var items = resXML.getElementsByTagName("item");
var itemNodes = items[i].childNodes;
// these are the pieces of data we want
var articleTitle = "";
var articleURL = "";
var articleImgURL = "";
var articlePubDate = "";
// loop over the child node of the item element
for (var j=0; j < itemNodes.length; j++) {
var itemNode = itemNodes[j];
if ("title" == itemNode.tagName) {
articleTitle = (itemNode.firstChild.nodeValue) ? itemNode.firstChild.nodeValue : itemNode.textContent;
} else if ("link" == itemNode.tagName) {
articleURL = (itemNode.firstChild.nodeValue) ? itemNode.firstChild.nodeValue : itemNode.textContent;
} else if ("media:content" == itemNode.tagName) {
articleImgURL = itemNode.getAttribute("url");
} else if ("pubDate" == itemNode.tagName) {
articlePubDate = (itemNode.firstChild.nodeValue) ? itemNode.firstChild.nodeValue : itemNode.textContent;
}
}
// build up the HTML string
contentStr += "<div class=\"article-div\">";
contentStr += "<img src=\"" + articleImgURL + "\" border=\"0\" width=\"60\" height=\"60\" align=\"left\" alt=\"Image\" title=\"Image\" class=\"article-img\" />";
contentStr += "<a href=\"" + articleURL + "\" title=\"Click to view\" class=\"article-link\" target=\"_new\">" + articleTitle + "</a><br />";
contentStr += "<span class=\"article-date\">" + articlePubDate + "</span>";
contentStr += "</div>";
}
// now the HTML is generated you can do anything with it...
// for this example, we will insert it into some HTML...
document.getElementById("articles-div").innerHTML = contentStr;
}
req.open("get", "http://rss.news.yahoo.com/imgrss/1600");
req.send();
//]]>
</script>
<!-- This some CSS that will style the contents -->
<style>
.article-img { margin-right: 2px; border:1px solid #ccc; }
#articles-header { font-size:9pt; font-weight:bold; font-family:verdana; color:#000; padding:3px }
#articles-div { border:1px solid #ccc; background-color:#666; width:260px; height:375px; overflow:scroll }
.article-div { border:1px solid #eee; background-color:#fff; height:75px; overflow:clip; margin-bottom:1px }
.article-link { font-size:8pt; font-family:verdana; color:#000; text-decoration:none }
.article-link:hover { font-size:8pt; font-family:verdana; color:#000; text-decoration:underline}
.article-date { font-size:8pt; font-family:verdana; color:#666; }
</style>
<!-- This is the shell HTML -->
<div id="articles-header"></div>
<div id="articles-div"></div>
When you are satisfied with the widget source, you can preview the widget on the preview tab (for this example, we don't have any parameters so we can skip the "Parameter" tab). For my fancy example, I would size the widget to 260px by 400px to accomodate the size of the <div> elements. To finish off, go to the Gallery Entry tab to fill in the widget information and provide a thumbnail image for the widget. The last step in the process is to submit the widget to the gallery... when it's approved, it will appear in the Widgtebox gallery!
Well, there it is. I hope this mini tutorial gives you some ideas for how to turn your favorite RSS feeds into a widget in Widgetbox! Happy Widgetizing smile
The widget example shown above is available in the Widgetbox gallery:
http://www.widgetbox.com/widget/yahoo-odd-news
