Minggu, 14 Agustus 2011 how to add Sleek Feed Widget With YQL, jQuery & CSS3


You will be surprised at how much data is made available on the web through RSS or ATOM feeds – twitter searches, your latest diggs, Google Search alerts, your own blog categories and so much more. You just have to look for that orange icon and you’ll surely find a lot more precious data, just waiting to be put into use.

Today we are making a sleek feed widget, that will fetch any feed and display it in your blog sidebar. You can set it up to show the latest posts from the different categories of your blog, your latest stumbles, or even people mentioning you on twitter.

So go ahead, download the demo archive from the button above, and keep on reading..
Problem Solving

Before stepping into development, we have to clarify for ourselves what we are aiming for, discuss some potential problems, and their solutions.
Problem 1 – Fetching Feeds

The widget is entirely front-end based, so we have to find a way to fetch the feeds directly with JavaScript. AJAX is a great technology, but there are security restrictions that limit it to fetching data only from the current domain. This means we cannot access feeds directly and display them.

This is where YQL comes along. It fetches the feed we want, and makes it available to our script as a regular JSON object that we can later loop and print to the page.

    YQL is a free API service from Yahoo, with which you can do much more than just download feeds. It acts as a gateway between you and other API’s and lets you manipulate them with a quick to learn SQL-like syntax (hence the name).

    You can reed more about it in this tutorial on nettuts, or go to the official YQL page.

Setting up YQL to work is tricky though (we have to dynamically include a <script> tag to the head section of the page, like we did in the Twitter Ticker tutorial few months back). Luckily, jQuery provides a method for just this purpose – getJSON. It does everything behind the scenes, so we don’t have to worry about the implementation.
Problem 2 – Different Feed Formats

As with everything else, feeds are available in a number of formats – RSS1, RSS2 and ATOM. They all have their differences and present a challenge, because our code has to be able to loop through the results returned by YQL and successfully display the entries.

The solution to this is to move the functionality that displays the feeds in a separate function and use a number of logical OR-s ( || ) throughout the code. It works with all the feeds that I tested it with, but you could easily make your own version of the function for special cases (for example displaying Flickr streams with a thumbnail).
Problem 3 – Insufficient Space

This is more of a layout problem actually, but is quite an important one. Given the limited width of the blog sidebar area, it becomes evident that it is impossible to display more than a couple of tabs simultaneously, if we go with the regular horizontal placement. So the best option is to have them show in a sleek drop down, which can store all the feeds one could possibly want.

With those issues addressed, we can now move on to development.
Step 1 – XHTML

The first part of the tutorial consists of laying down the XHTML structure for the feed widget. The snippet below (extracted from demo.html in the download archive) is everything you need to show the widget on your page (apart from the CSS and jQuery files, covered in the later steps).
demo.html
<div id="feedWidget">

    <div id="activeTab">

<!-- The name of the current tab is inserted here -->
    </div>

    <div class="line"></div>

    <div id="tabContent">
        <!-- The feed items are inserted here -->
    </div>

</div>
Now lets move to the next step.
Feed Widget With jQuery, CSS3 & YQL

Let’s take a look at the style.
The CSS  Add before tag ]]></b:skin> :
<style type='text/css'>


#feedWidget{
    background:url(bg.png) repeat-x #212121;
    border:0px solid #212121;

    width:100%px;
    padding:5px;
    position:relative;
   
    /* Remains hidden if JS is not enabled: */
    display:none;
    z-index:20;
}


#activeTab.hover,.dropDownList{
    background:url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLRsrwe0wHdLH5EkbFW_wIxro2lh79aqp2B6lj0LqzeZ5CWtFUQIfbWTv7R3nqEIMUnz_mrTPAH9P1NowxDJqTeMijYeTHvEsYk4KRn9gY9tHfJNI15uZyng-2P6sp8cCuXREwFVBDtJY/s800/drop_arrow.png) no-repeat 95% 50% #252525;
    border:1px solid #333333;

    margin:-1px;
   
    cursor:pointer;
   
    /* CSS3 round corners: */
    -moz-border-radius:5px;
    -webkit-border-radius:5px;
    border-radius:5px;
   
}

#activeTab,.dropDownList div{
    color:white;
    cursor:pointer;
    font-size:20px;
    margin:0 0px 0 0;
    padding:5px;
   
    text-shadow:0 1px 1px black;
}

.line{
    height:1px;
    overflow:hidden;
    background-color:#cc0000;
    border-bottom:1px solid #cc0000;
    margin:3px 0;
        -moz-box-inner glow:0 1px 1px red;
}

.dropDownList{
    background-image:none;
    position:absolute;

    border-top:none;
    padding:0px;
   
    /* We reset the roundness of the top corners, inherited by a previous rule: */
   
    -moz-border-radius-topleft: 0;
    -moz-border-radius-topright: 0;
    -webkit-border-top-left-radius: 0;
    -webkit-border-top-right-radius: 0;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.dropDownList div:hover{
    background-color:#191919;
}

#tabContent div{
    /* The feed entry divs */
   
    background-color:#313131;
    color:#818181;
    font-size:10px;
    margin-bottom:10px;
    padding:5px;
    position:relative;
   
    -moz-border-radius:5px;
    -webkit-border-radius:5px;
    border-radius:5px;
   
    -moz-box-shadow:0 1px 1px black;
    -webkit-box-shadow:0 1px 1px black;
    box-shadow:0 1px 1px black;
}
</style>
]]></b:skin>

We apply a number of CSS3 rules here: border-radius for pure CSS rounded corners and box-shadow for adding a drop shadow below the feed items. They are provided with the -moz- and -webkit- vendor prefixes, because the regular version is not yet supported in any browser (but we supply it as well for future-proofing).
The Dropdown

The Dropdown
Step 3 – jQuery

After including the jQuery library into the page, it is now possible to leverage the methods it provides and build some complex interactions that would otherwise be impossible (or at least would take too much development resources).  The JavaScript code is located in scripts.js in the demo files.
script.js – Part 1
<script type='text/javascript'>
//<![CDATA[
/* Configuration: */

var tabs = {
    "@Your Twiter id" : {
        "feed"        : "http://twitter.com/statuses/user_timeline/natamp3.rss",
        "function"    : twitter
    },
   
    "Latest Post": {
        "feed"        : "http://feeds.feedburner.com/Natamp3",
        "function"    : rss
    },
   
    "Smashing Mag": {
        "feed"        : "http://rss1.smashingmagazine.com/feed/",
        "function"    : rss
    },
   
   
    "Nata @ Buzz"    : {
        "feed"        : "http://buzz.googleapis.com/feeds/107171907643887373658/public/posted",
        "function"    : buzz
    }
}

var totalTabs;
$(document).ready(function(){
    /* This code is executed after the DOM has been completely loaded */
   
    /* Counting the tabs */
    totalTabs=0;
    $.each(tabs,function(){totalTabs++;})
   

    $('#feedWidget').show().mouseleave(function(){
       
        /* If the cursor left the widet, hide the drop down list: */
        $('.dropDownList').remove();
        $('#activeTab').removeClass('hover');

    }).mouseenter(function(){
       
        if(totalTabs>1) $('#activeTab').addClass('hover');
       
    });

    $('#activeTab').click(showDropDown);

    /* Using the live method to bind an event, because the .dropDownList does not exist yet: */
    $('.dropDownList div').live('click',function(){
       
        /* Calling the showDropDown function, when the drop down is already shown, will hide it: */
        showDropDown();
        showTab($(this).text());
    });
   
   
    /* Showing one of the tabs on load: */
    showTab('@Natamp3');
   
});


function showTab(key)
{
    var obj = tabs[key];
    if(!obj) return false;
   
    var stage = $('#tabContent');
   
    /* Forming the query: */
    var query = "select * from feed where url='"+obj.feed+"' LIMIT 5";
   
    /* Forming the URL to YQL: */
    var url = "http://query.yahooapis.com/v1/public/yql?q="+encodeURIComponent(query)+"&format=json&callback=?";
   
    $.getJSON(url,function(data){

        stage.empty();

        /* item exists in RSS and entry in ATOM feeds: */
        $.each(data.query.results.item || data.query.results.entry,function(){
            try{
                /* Trying to call the user provided function, "this" the rest of the feed data: */
                stage.append(obj['function'](this));
               
            }
            catch(e){
                /* Notifying users if there are any problems with their handler functions: */
                var f_name =obj['function'].toString().match(/function\s+(\w+)\(/i);
                if(f_name) f_name = f_name[1];
               
                stage.append('<div>There is a problem with your '+f_name+ ' function</div>');
                return false;
            }
        })
    });
   
    $('#activeTab').text(key);
}

function showDropDown()
{
    if(totalTabs<2) return false;
   
    if($('#feedWidget .dropDownList').length)
    {
        /* If the drop down is already shown, hide it: */
        $('.dropDownList').slideUp('fast',function(){ $(this).remove(); })
        return false;
    }
   
    var activeTab = $('#activeTab');
   
    var offsetTop = (activeTab.offset().top - $('#feedWidget').offset().top )+activeTab.outerHeight() - 5;
   
    /* Creating the drop down div on the fly: */
    var dropDown = $('<div>').addClass('dropDownList').css({

            'top'    : offsetTop,
            'width'    : activeTab.width()
   
    }).hide().appendTo('#feedWidget')
   
    $.each(tabs,function(j){
        /* Populating the div with the tabs that are not currently shown: */
        if(j==activeTab.text()) return true;
       
            $('<div>').text(j).appendTo(dropDown);
    })
   
    dropDown.slideDown('fast');
}

function twitter(item)
{
    /* Formats the tweets, by turning hashtags, mentions an URLS into proper hyperlinks: */
    return $('<div>').html(
            formatString(item.description || item.title)+
            ' <a href="'+(item.link || item.origLink)+'" target="_blank">[tweet]</a>'
    );
}

function rss(item)
{
    return $('<div>').html(
            formatString(item.title.content || item.title)+
            ' <a href="'+(item.origLink || item.link[0].href || item.link)+'" target="_blank">[read]</a>'
    );
}

function buzz(item)
{
    return $('<div>').html(
            formatString(item.content[0].content || item.title.content || item.title)+
            ' <a href="'+(item.origLink || item.link[0].href || item.link)+'" target="_blank">[read]</a>'
    );
}

function formatString(str)
{
    /* This function was taken from our Twitter Ticker tutorial - http://tutorialzine.com/2009/10/jquery-twitter-ticker/ */
    str = str.replace(/<[^>]+>/ig,'');
    str=' '+str;
    str = str.replace(/((ftp|https?):\/\/([-\w\.]+)+(:\d+)?(\/([\w/_\.]*(\?\S+)?)?)?)/gm,'<a href="$1" target="_blank">$1</a>');
    str = str.replace(/([^\w])\@([\w\-]+)/gm,'$1@<a href="http://twitter.com/$2" target="_blank">$2</a>');
    str = str.replace(/([^\w])\#([\w\-]+)/gm,'$1<a href="http://twitter.com/search?q=%23$2" target="_blank">#$2</a>');
    return str;
}
//]]>
</script>

In the last part of the code, we have the two functions – twitter and rss. These take an object passed from the $.each loop in showTab() and find their way to the link and title of the feed item, depending on whether it is RSS or ATOM.


Change your defaul show 

/* Showing one of the tabs on load: */
   showTab('@Your Twiter id');

You can create your own functions and include them in the tabs object. This way you can expand the functionality for feeds that are not limited to text. It is only important that you return the results as a ‘<div>….</div>’ string. widget by nata http://natamp3.blogspot.com

0 komentar:

Posting Komentar

 
✪ Copyright © 2011 Baramp3 | design by Natamp3