Feed widget with YQL & jQuery

Over on my other site (Salathe, just a single page site) I felt that keeping the page static was a little bit boring: it needed some life injected into it. That life, I decided, would be a summary of my recent blog posts on here. They don’t come all too often but I figured it would be nice to syndicate them across there and maybe help people find out a bit more about me if they land on the Salathe site.

Preamble

I could’ve gone the server-side route; use PHP to grab the feed from here (well, Feedburner actually), parse it (probably with SimpleXML for simplicity) and display it with my desired HTML. And that’s a perfectly acceptable approach. However, since the feed content is only really an added extra I didn’t want to add the feed content to the HTML page and have that overwhelm the main content on there (the introduction and contact info). Because of that, I decided to take the client-side approach using JavaScript to grab, parse and inject our feed into the page.

The Feedburner feed, as is usual for feeds, comes in XML format and due to the security restrictions of browsers I can’t just go and grab that with JavaScript. Besides, I didn’t want the whole feed anyway: who wants to load in a 38kb feed just to grab some headings? (What I do end up grabbing is around 4kb.)

Introducing YQL

To grab only what I want, and to provide a format that I can actually get at, as well as to satisfy a niggling urge to put it into some practical use, I headed over to Yahooland and made use of the awesome tool that is YQL. YQL provides a SQL-like syntax for getting at the structured data (feeds are structured data!) around the web. It allows me to ask for specific items of data from the web, such as “give me the title and permalink for the last 10 items from Yahoo news” for example. There’s a huge range of data that YQL can get its hands on (stopping just short of the entire web) but that’s beyond the scope of this blog entry. The service also allows me to get responses in XML or JSONP, the latter being important because I can grab this from a remote domain name without the security restrictions coming into play.

Querying for data

So to get at my feed, I can simply issue the query:
Try it yourself

SELECT * FROM feed WHERE url='http://feeds2.feedburner.com/cowburn'

For my little widget, I don’t really need everything brought back by that query. Firstly, I only want the latest 5 items instead of the 10 that Feedburner provides. Secondly, I only really need the title, date, link and excerpt for each blog entry. The Feedburner feed provides extra information like the comments link, tags, and the full HTML content of the entry. Grabbing only what I need shrinks down the size of the data coming down the pipe and results in things getting done faster. I mentioned before that I wanted the results in JSONP format which is a simple enough task: just click the JSON radio button in the YQL console, or add “format=json&callback=cbfunc” (where cbfunc is your callback function name) to the REST query URL. So to grab only what I want, the following YQL query is used: Try it yourself

SELECT title, description, link, pubDate
FROM feed(0,5)
WHERE url='http://feeds2.feedburner.com/cowburn'

Aside: the (0,5) limits YQL to the first 5 items in the Feedburner feed.

Right, now we have the data that we want and can get it in JSONP format. How do we go about doing that exactly? JavaScript time!

Retrieving the JSONP with jQuery

I really like using jQuery for adding in extra goodness to sites and I was already using it for a little piece of DOM manipulation on the page (interesting but not to be covered in this post). Plus, jQuery makes grabbing JSONP content very, very simple indeed using its jQuery.getJSON (docs) function. Basically we provide that function with an URL to the JSON document and a callback function to execute once jQuery has grabbed it. See the docs for examples.

Creating a widget

Generally, there’s a logical structure to creating a widget like this one. Steps involve grabbing the required data, parsing it, building the HTML and attaching it to the page. Since this would take an inordinately long time to explain step by step (perhaps some other intrepid blogger has already done it) I’ll just show you with code. Below is the JavaScript—in jQuery plugin form though that isn’t particularly necessary or important (just means it’s all wrapped up neatly and only concerned with itself). There are a number of variables to hold HTML, the YQL URL and a number of functions which parse the JSON object into HTML form and a little bit of effects to fade in the HTML block when it’s all ready. There’s also a function to parse the dates from “Mon, 05 Jan 2009 16:28:34 +0000″ into “5 Jan” form.

Put simply, the widget code just says, “when the page is loaded, ask YQL for the filtered feed, parse the response items into a HTML list and inject it into my page just above the footer.”

The widget code

// Grab food!
(function($){
    jQuery(function(){
   
        var wrapper = $('<div id="widget_blog">'
                    + '<h4>From the <a href="http://cowburn.info" rel="me">blog</a>:</h4>'
                    + '<ul></ul>'
                    + '</div>');
        var list    = wrapper.children('ul:first');
        var style   = $('<style type="text/css">@import url(assets/feed.css);</style>');
        var service = "http://query.yahooapis.com/v1/public/yql?q=select%20title%2C"
                    + "description%2Clink%2CpubDate%20from%20feed(0%2C5)%20where%20url%3D'"
                    + "http%3A%2F%2Ffeeds2.feedburner.com%2Fcowburn'&format=json&callback=?";
       
        var callback = function(data) {
            if ( ! (data && data.query && data.query.results && (items = data.query.results.item))) {
                // Unexpected response from YQL service
                return;
            }
           
            // Inject HTML before the footer
            $('.footer:first').before(wrapper);
            wrapper.before(style).hide();
            $.each(items, display_item);
            wrapper.fadeIn("slow");
        };
       
        var parse_date = function(str) {
            var d = new Date(str);
            var m = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];
            return d.getUTCDate() + ' ' + m[d.getUTCMonth()];
        };
       
        var display_item = function(index, item){
            var tpl = '<li><span>%date: </span><a href="%link" title="%extract">%title</a></li>';
            var html = tpl.replace(/%link/g, item.link)
                          .replace(/%extract/g, item.description)
                          .replace(/%title/g, item.title)
                          .replace(/%date/g, parse_date(item.pubDate));
            list.append(html);
        };
       
        // Actually grab the feed now
        $.getJSON(service, callback);
       
    });
   
})(jQuery);

As well as the HTML to display the feed items, the widget also adds a CSS stylesheet to add a little bit of formatting: link. The widget code itself (which may change in the future) can be found here.

End result

What we’re left with is a neat little list of my last 5 blog entries.

Salathe.co.uk before/after widget

Salathe.co.uk before/after widget

Previous
Next

6 Comments on Feed widget with YQL & jQuery.

Add your two pennies, others have already donated theirs.

  1. jak
    jak
    Jul 5 2009 at 12:46 UTC

    can you please email me the source code in a file I think this is a very cool tutorial but i get a 404 when tring to get the code
    thank allot
    jak

  2. Peter
    Jul 5 2009 at 15:25 UTC

    The code within the article is all that the link originally pointed to. I’ve since changed the site so the links don’t point to the old files any more. However, I’ve updated the links again in this article to point to some slightly more permanent URLs.

  3. will
    will
    Jan 3 2010 at 09:45 UTC

    Thanks a bunch for the feedburner-YQL url, just what I needed.

  4. Andrei
    May 8 2010 at 23:32 UTC

    Peter,

    Nice article. It helped me a lot when I was working on my custom Facebook Fan Box Widget. However, I think that $.getJSON should be changed to $.ajax , so you can control timeouts and handle errors if something goes wrong. Thanks a lot for your work on this!

  5. Peter
    May 9 2010 at 09:58 UTC

    Andrei, absolutely. $.ajax would allow a little more precision in how the AJAX has handled. Also, it is a good idea to use a named callback to help with caching results (see Avoiding rate limits and getting banned in YQL and Pipes: Caching is your friend on the YQL blog). I’ve been working a lot with YQL recently so there may well be more (up-to-date) articles coming.

  6. Maria
    Maria
    May 3 2011 at 17:28 UTC

    Great article, thanks. …but where exactly does the widget script go? Is that a head script? If so, how does it get called into the HTML? I’m a bit confused on this. I think I’m off with something minor and want to double check this concept. Any insight would be greatly appreciated.

Post Comment