Back to my page

Developers


Building a Twitter widget, part 2: displaying the public timeline

This is part 2 of our series of articles on building a complete Twitter widget, all the while exploring the functionalities of UWA and learning some good practices of widget developing. If you haven’t already, read the first part, where we set up the basic widget code, and customize it to display a single, known Twitter status.

That first example had its limits, starting with the fact that you had to know the status ID beforehand, and that displaying only one status remains a tad useless. That’s why we’ll start from that first code, and change it to display the content of the whole feed for the public timeline, using Twitter’s timeline method. This way, we will discover how to use the UWA.Data.getFeed method, how to add CSS styles and how to use templates.

Twitter 02: the public timeline

If you want to follow along, download and work with our previous version of the widget.

Changing the preferences

The previous version of the widget dealt with a single status. The preference was as simple as this:

<preference name="id" type="text" label="Status ID"
  defaultValue="44739202" />

Since we won’t directly target a single status anymore, we can remove this line. But that doesn’t mean we can’t let the user decide how to display the content. For now, we will let the user simply choose how many entries to display. To that effect, we’ll use a preference of the range type, since we know the feed features 20 items:

<preference name="limit" type="range"
  label="Number of items to display" defaultValue="10"
  step="1" min="1" max="20" />

This code is directly lifted and adapted from our basic RSSReader sample widget. You can see the available preference types on the documentation site.

The HTML code won’t need much of a change for now, we’ll keep it as is.

Adapting the Ajax request code

We’re not displaying a single status anymore, but a series of statuses. That implies some more thoughts on the JavaScript code.

First, the feed URL is obviously changing. Our new Twitter.onLoad method now looks like this:

Twitter.onLoad = function() {
  UWA.Data.getJson(
    'http://twitter.com/statuses/public_timeline.json',
    Twitter.display);
}

We’ve decided to use the JSON feed, since it’s easier to work with in JavaScript. That being said, it’s format is less predictable (each service uses its own variation: Twitter, Flickr, del.icio.us…), so those who would rather know what they can expect should use the RSS 2.0 or Atom 1.0 version of the feed (just replace the .json file extension by .rss or .atom), and use the UWA.Data.getFeed method rather than the UWA.Data.getJson one. Check out the various ways of accessing data using UWA’s Ajax methods.

Revamping the display code

Twitter.display() is next in line in our data processing. Since we don’t display one status, but a series of them, we have to parse the JSON feed with a proper loop. That loop should stop parsing when it reaches the number of items requested by the user in his preference setting.

Thanks to JSON, this loop is very intuitively built: items are just part of a JavaScript array, ready to be parsed. We know what the item names are because we took the time to study the default JSON output’s format (using the cURL tool or directly within the browser, using the url http://twitter.com/statuses/public_timeline.json):

[
  {
  "created_at":"Tue Jun 05 14:28:57 +0000 2007",
  "text":"bla bla bla bla bla",
  "id":123456789,
  "user":
    {
    "name":"John Doe",
    "description":"My description",
    "location":"City, Country",
    "url":"http:\/\/www.example.com\/",
    "id":123456,
    "protected":false,
    "profile_image_url":"http:\/\/assets3.twitter.com\...",
    "screen_name":"MyUsername"
    }
  }
,
  {
  "created_at":"Tue Jun 05 14:28:57 +0000 2007",
  "text":"patati et patata et patati",
  "id":123456790,
(...20 items in the feed...)
    }
  }
]

The basic code turns out like this:

Twitter.display = function(json) {
  var count = 0;
  for (var i = 0; i < json.length; i++) {
    var status = json[i];
    var p = widget.createElement('p');
    p.setHTML(
      '<img width="32" height="32" src="'
      + status.user.profile_image_url + '" /> '
      + ''
      + status.user.screen_name + ': '
      + status.text
    )
    widget.body.appendChild(p);
    count++;
    if (count == widget.getValue('limit')) break;
  }
  widget.callback('onUpdateBody');
}

The Ajax request returns an array, which contains the JSON data. We can directly parse every item using var status = json[i]. Each status is an JavaScript object, which you can easily access the properties of, like status.text or status.user.profile_image_url.
The date, available at status.created_at, uses a non-standard format, so we pass that data to a custom function, Twitter.date, to get a true Date object that we can use in our code.
All of these data are put in a dynamically-created p tag. Note that only dynamically-created tags, using widget.createElement() for instance, are UWA-extanded by default. Hand-created elements can be extended through the UWA.$elements(elementTagName) method, as we will see in another part.

Right after the loop has entirely parsed the wanted content, we set up a call on the onUpdateBody callback method, which indicates that the body content has been updated, and that it should try and resize itself in order to display it all correctly.

The complete code features a bit more code, notably for handling the timestamp display.

Styling it all

Displayed as is, the result is not very pretty: images and texts are not aligned correctly, and it’s hard to tell the difference between two statuses. This is where we can make good use of CSS classes.

Twitter 02: no CSS style

We first have to add classes to the p element that we created dynamically. This is how we do it, directly in the loop:

(...)
var p = widget.createElement('p');
p.setAttribute('class', 'status');
if (count % 2 == 0)
  p.addClassName('odd');
else
  p.addClassName('even');
p.setHTML('<img ...
(...)

In order to differentiate statuses, we add a second class, 'odd' or 'even', depending on the count variable.

Classes being in place, the only thing left is to set the style-sheet. This is done directly in the HTML code:

<style>
p.status {
  margin: 5px 0;
  padding: 5px;
  min-height: 36px;
  clear: both;
  }

p.status img {
  float: left;
  margin-right: 5px;
  }
</style>

The even and odd classes are dealt with by UWA’s CSS, so you don’t have to set those yourself, they will automatically adapt to the current theme. That being said, you can overload them with your own CSS rules.

Every designer is free to choose how to style his data. Note that if you want to conform to the user’s current theme, you might prefer to use a UWA template, like the Thumbnailed List one.

We’re done for now, the public timeline displays in a nice way, and that was our aim. Check out the code for this new version of our Twitter widget. The next part will focus on paging and automatic preference handling.

Tags: , , , , , , ,

Leave a Reply


Business

Click here if you want to know more about how netvibes can help you widgetize your brand and connect to your audience.

Developers

Click here to learn about netvibes open widget platform and how you can create cool widgets for your service or your application that run everywhere.

Community

Click here to know how to join the netvibes community, get involved and help us translate and create a global directory of widgets for netvibes

Media

Click here to access informations about the company, our latest press release, our logos and media kit