Subscribe

Wednesday 3 March 2010

How to create widgets Part4 Custom RSS Feed

Hi there everybody, it has been a few days since my last post, sorry for the delay. We had this big festival thus it was impossible to concentrate, okay in my last post, I had shown you how to develop a little News Reader for your self.
Please refer to my earlier post here.Let us take this concept a bit further as promised. The RSS feed was one of my favourite it may not be yours too thus there must be a way to change it.
As you must have noticed Yahoo provides the widget preference option for you, just right click anywhere on the widget body or click on the setting icon shown above your widget icon in the dock bar. Most widgets provide you with some level of customization.
As mentioned above why dont we start with one simple preference of changing the the news feed according to the user choice.

Some Theory

A Widget can provide a number of preference objects to allow itself to save out settings. These settings
are saved out in per-user preference storage.
• On the Mac, this is in ~/Library/Preferences/Konfabulator .
• On the PC, this is in HKEY_CURRENT_USER\Software\Yahoo\WidgetEngine .
You can define preferences in the XML:
<preference hidden="true" name="windowLevel" value="1">
<preference hidden="true" name="windowOpacity" value="0.7">
And get and set preference objects in JavaScript:
preferences.windowOpacity = "0.9";
print(preferences.windowOpacity);
If your Widget will be saving large amounts of data, consider using the SQLite embedded database
available within the engine.
(reference Yahoo SDK Manual)


Practical
Please open your kon file in an editor of your choice and lets insert few basic entries to customize the feed
<preference name="NewsFeed">

  <type>popup</type>
  <title>Add Feed </title>
  <type>text</type>
  <value>http://www.deccanherald.com/rss/69/news.html</value>
 </preference>
 <preference name="Title">
   <type>popup</type>
   <title>Feed Title </title>
   <type>text</type>
 </preference>

 <preference name="refresh">
  <type>popup</type>
  <title>Refresh Interval </title>
  <type>text</type>
 </preference>

These are choices which user may change. Even though the preferences are quite easy yet..........
NewsFeed preference gives you a chance to get your own favourite feed displayed and not have a static page.
Title preference generated the window title based on the feed, it reads the title of the feed and displays it in your bar refresh preferences gives you anoption to specify the seconds after which the window will fetch the feed again to refresh the contents.
This entry should be kept outside your window element. As this is not the part of the main window.
When these preferences are changed there is an event which is generated called onPreferencesChanged. We will write an event handler for this because user has made some changes which will effect the program
Where we had declared the onLoad trigger, just below it we will write
<action trigger="onPreferencesChanged">
  readRSS();
 </action>
Presently our changes are simple enough to be handled in the same function later on when we have more complicated preferences we might use a separate event handler

Javascript Part

Lets see how we can modify our javascript to read the user preference to load a new feed
The problem is that we have no way of knowing if the user has given any preferences or left the preference field blank. To mitigate that problem please add the next few lines at the top of your readRSS() function
var news=preferences.NewsFeed.value;
if(news.length<8)
  news="http://timesofindia.indiatimes.com/rssfeeds/-2128936835.cms";
Simply if the preference entry is not present we provide a hardcoded one(not the most elegant but lets keep it simple)
Use the same variable in your HTTP send operation
var timer=widget.getElementById("rss1timer");
 if(timer!=null)
 {
  timer.ticking=false;
  var timer_time=preferences.refresh.value;
  if(timer_time=="")
   timer.interval=500;
  else
   timer.interval=timer_time;
  
 }
 preferences.refresh.value=timer.interval;
as mentioned earlier in my previous article when timer event fires it calls the main readRSS() function where we check if there is a preferred value for interval ,if not we provide the timer with one
var win_title=widget.getElementById("winTitle");
This statement will get the title bar text object and initialize with a user given title if available in preferences or get the title from the RSS feed and stores it as the preference called Title(as defined in the Kon file)
win_title.data=preferences.Title.value;
  if(win_title.data=="")
  {
   var temp_titles=xmldoc.evaluate("rss/channel/title");
   win_title.data=temp_titles.item(0).firstChild.data;  
  }
    
  preferences.Title.value=win_title.data;
I have tried to explain the code in piece meal form lets see the whole XML in the kon file
<?xml version="1.0" encoding="UTF-8"?>
<widget minimumversion="4.5">
<script charset="utf-8" src="RssRead.js">
</script>
<window id="mainWin">
 <name> RSS1</name>
 <title> My Rss Widget</title>
 <width>400</width>
 <height>310</height>
 <visible>true</visible>

  <img >

    <src>Resources/widget.png</src>
  </img >
  <img >
    <src>Resources/wintitle.png</src>
    <voffset>-1</voffset>
 </img >

  <text id="winTitle" style="font-size: 24px;">
    <hoffset>15</hoffset>
    <voffset>15</voffset>
    <size>16</size>
    <color>#f0fff9</color>
  </text>

  <web id="rss1">

    <font>Times New Roman</font>
    <size>14</size>
    <voffset>28</voffset>
    <hoffset>18</hoffset>
    <width>380</width>
    <height>270</height>
    <bgcolor>#ffaa55</bgcolor>
</web>
</window>

  <timer id="rss1timer" name="rss1timer1">
    <ticking>false</ticking>
    <ontimerfired>readRSS();</ontimerfired>
    <interval>20</interval>
  </timer>

  <preferencegroup name="RSS" title="RSS">

     <type>popup</type>
  <title>Add Feed </title>
  <type>text</type>
  <value>http://www.deccanherald.com/rss/69/news.html</value>
 </preference>
 <preference name="Title">
   <type>popup</type>
   <title>Feed Title </title>
   <type>text</type>
 </preference>

 <preference name="refresh">
  <type>popup</type>
  <title>Refresh Interval </title>
  <type>text</type>
 </preference>
</preferencegroup>

  <action trigger="onLoad">

     readRSS();

  </action>

  <action trigger="onPreferencesChanged">

       readRSS();

  </action>

</widget>
Now lets have a quick peak in our js file
function GetXmlHttpObject()
{

  return new XMLHttpRequest();
}

function readRSS()
{
 var news=preferences.NewsFeed.value;
 if(news.length<8)
    news="http://timesofindia.indiatimes.com/rssfeeds/-2128936835.cms";
 var timer=widget.getElementById("rss1timer");
 var win_title=widget.getElementById("winTitle");
 if(timer!=null)
{
  timer.ticking=false;
  var timer_time=preferences.refresh.value;
  if(timer_time=="")
    timer.interval=500;
  else
    timer.interval=timer_time;
}
 xmlhttp=GetXmlHttpObject();
 if (xmlhttp==null)
 {
   alert ("Something has gone wrong");
   return;
 }

 xmlhttp.onreadystatechange=function()
 {
   if (xmlhttp.readyState==4)
   {
     xmldoc=xmlhttp.responseXML;
     if (xmlhttp.status==200 && xmldoc!=null)
     {
        win_title.data=preferences.Title.value;
        if(win_title.data=="")
        {
           var temp_titles=xmldoc.evaluate("rss/channel/title");
           win_title.data=temp_titles.item(0).firstChild.data;
        }
        preferences.Title.value=win_title.data;
        var titles=xmldoc.evaluate("rss/channel/item/title");
        var links=xmldoc.evaluate("rss/channel/item/link");
        var strAnswer=""
        for(var i = 0; i < titles.length; i++)
        {
          strAnswer=strAnswer + "<a href='" + links.item(i).firstChild.data + 
          "' target='_self' style='color:white; textDecoration:none'>"+(i+1)+ " : "   +titles.item(i).firstChild.data + "</a><br/>";
        }
       var result=widget.getElementById("rss1");
       result.html=strAnswer;
       timer.ticking=true;
     }
     else
     {
       result.html="An error has occurred";
       timer.ticking=true;
     }
   }
 }

 xmlhttp.open("GET", preferences.NewsFeed.value, true)
 xmlhttp.send(null)
}


Please do not forget to subscribe to my feed for the latest and visit me on youtube for further video tutorials

In the next post we will look into using some kind of animation to let the user know while he/she waits and we will look into sqllite with widgets, before that I may delve into sidebars, I have been thinking of doing so for quite some time .

No comments:

Post a Comment

 
EatonWeb Blog Directory