The first half of this tutorial introduced you to making a rudimentary but functional widget of the sort you can find on Yahoo’s site since its purchase of Konfabulator. In this article, you’ll add the finishing touches to increase its functionality.Widget Walkthrough

The preferences that you created in the first part of this article won’t actually do anything on their own; they’ll need the following JavaScript in order to actually make the required changes:

<action trigger=”onLoad”>
<![CDATA[
function updatepreferences() {
datatextarea.font = preferences.textfontpref.value;
datatextarea.color = preferences.textcolorpref.value;
datatextarea.size = preferences.textsizepref.value;
datatextarea.style = preferences.textstylepref.value;
}
updatepreferences();
]]>
</action>
<action trigger =”onPreferencesChanged”>
updatepreferences();
</action>

As you can see, each action (onLoad and onPreferencesChanged) is contained within its own <action> element. All each line of the updatepreferences() function is doing is setting the attributes of the textarea element, much as CSS would with HTML. I’ve included the opening CDATA tag as we’ll need it for one of the next functions.

Widget Walkthrough – Getting the headlines

Now you need to actually get the news headlines from the BBC web server. To do this, you’ll need to make use of the URL widget engine object:

function getdata() {
var url = new URL();

url.location =
“http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/
technology/rss.xml”;
feeddata = url.fetch();
}
getdata();

This will instruct the widget to fetch whatever file is waiting at the above URL. You now need to display the file:

function setdata() {
datatextarea.data = feeddata;
}
setdata();

This function can be added into the existing onLoad <action> and simply creates a new URL object, sets the location attribute to the source of the feed, and then retrieves the information as the specified location. At this point, you should have something that looks a little like this:

widget_feeding.jpg

The function works; it grabs the file located at the target URL, but unfortunately, this happens to be in an XML format! This means our textarea is currently displaying the entire XML file! Another function, to traverse the XML document and pull out just the headlines, is going to be needed. Fortunately, the widget engine provides XPath 1.0 support to make extracting the required items relatively easy.

There are several steps involved in getting the data that we want; if you look at the XML document obtained by the url.fetch command, you’ll see that the news headlines we want to grab appear in an element called title, which is a child of the item element, which is a child of the channel element, which finally, is a child of the rss element. Therefore, the element we need is a great-grandchild of the root element. Remove the setData() function as we can extend the getData() function to display the headlines once they have been extracted.

Widget Walkthrough – Using loops

The Widget reference manual states that you should use a try catch loop to perform XPath functions, so you can add one to your getData() function. You will first need to obtain the XML document and place it in a variable using the parse method:

try {
doc = XMLDOM.parse(feeddata);

Next, you need to specify which elements in the XML file you want to match. This is the XPath element of your function:

titlelist = doc.evaluate( “rss/channel/item/title” );
datatextarea.data = “”;

You now need to create an array to hold the headlines as separate DOMElement objects:

titles = new Array();

In this particular rss file, there are always 19 headlines, however, if you were using a different feed, you may not know the number of headlines in advance so it is a good idea to use a for loop that operates on the length of your array:

for (n = 0; n < titlelist.length; n++) {

The DOMNodeList returned by the XPath function has a built-in property of item() which can be used to specify which DOMElement in the list you are referring to. In this case, we can match the number of the array item with the item we want to store in the array:

titles[n] = titlelist.item(n);

Finally, each time the loop iterates, you can set the data property of the <textarea> to the data held in the array item. The actual item held in the array is the DOMElement; to get the actual text held in the object you need to address the firstChild of the element. The JavaScript new line character is also specified (twice) to break up the headlines:

datatextarea.data += titles[n].firstChild.data + “nn”;
}
}
catch(e) {
print(e);
}

Widget Walkthrough – Fine tuning headline retrieval

If you save the changes and reload the file now, the headlines should appear as if by magic! Using the <textarea> is good because it makes setting the preferences easy and handles the word wrapping well. One major flaw of this though is that it’s not possible to set the URL of each individual headline. To compensate for this, you can add a right-click menu item to the widget that takes you to either the main news front page, or a page containing the list of headlines displayed. To do this, you can add the following code block to the <textarea> element:

<contextMenuItems>
<menuItem title=”Open BBC Technology News”>
<onSelect>openURL
(”http://news.bbc.co.uk/1/hi/technology/default.stm”);</onSelect>
</menuItem>
<menuItem title=”Open the actual headlines page”>
<onSelect>openURL
(http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/technology/rss.xml);
</onSelect>
</menuitem>
</contextMenuItems>

This at least provides you with a way of reading the full news stories. Another thing that you need to consider is a way of updating the file used as the source of the data; if the computer and widget are left running, the reader will just display the same data, forever. A timer element can be used to specify that an action could be carried out repeatedly on a set interval:

<timer>
<interval>10</interval>
<onTimerFired>getdata();</onTimerFired>
</timer>

The interval is measured in seconds, but this kind of widget wouldn’t really need to grab a new rss file every ten seconds. Depending on the frequency of updates at the source, you could probably set it to update maybe several times daily.

widget_finished.jpg

Widget Walkthrough – Publishing your widget

In order to get your widget published on the Yahoo! Widget Gallery, you need to switch off debugging and package your widget. Right at the top of the file, you’ll find the <debug> element; set this to off. To package the application and produce the flat, one-file version of the existing files and folder structure, you’ll need to get to grips with the command line interface (CLI) included in the SDK. The converter is situated (on a Windows XP system) at the following location:

C:Program FilesYahoo!Yahoo! Widget Engine

You need to create an output directory at this stage so create a folder, also at the above location, called feeder or something similar. Now open a command prompt. It will probably open (on a Windows XP system) in your My Document folder so you’ll need to use the cd (change directory) command to browse to the location of the CLI. You should also move your widget folder into the same directory as the CLI and output directory. Once this has been done, use the following command to package your creation:

converter_4a convert -v -flat TechFeeder.widget -o outputDirName

You should then end up with a flat file package containing all of the files that make up the widget in the output folder. Your widget should now be ready to go onto the gallery, but don’t submit this one (because I already have).

The tagline displayed on the home page of the Widget gallery is “The grass is greener on both sides” which pays homage to widgets’ cross platform compatibility. When creating widgets, you should ensure that you test your widget on a Mac and that it runs on both Mac and Windows platforms. I have tested this widget on a Mac and unfortunately, it doesn’t work as well as it does on Windows systems; instead, it just displays the first headline. I don’t actually know why this is, but I am investigating. In the meantime however, I’ve specified on the gallery that it’s Windows only. Also, the Widget optimizer tool is supposed to be used to remove unnecessary memory forks on widget created on the Mac, but like the converter tool it isn’t currently available, so for the time being, those of you on Macs I guess will have to forgo this at present.

There is a lot more that could be done to refine the widget. At this stage it really is just a version 1.0 release. You could add a function that automatically scrolls the headlines perhaps, or create the headlines as individual text elements, each with their own URL property to make them clickable links to each of the news stories, or even include the description in a title element that displays when the mouse runs over each text element; the possibilities are endless. But what you have now is a very basic, but fully functional widget, produced with ease and in not much time at all. This is the beauty of the Yahoo! Widget Engine, speed and ease of deployment and fully functional information management right on your desktop.