Back to my page

Developer Blog



Building a Twitter widget, part 1: setting-up the code and displaying a single status

With the introduction of authentication methods in UWA (see the complete documentation) comes the ability to build some much more interesting widgets, ones that can access private data securely, both in read and write mode (HTTP GET and POST).

In order to present authentication to you, we’ve built a Twitter widget able to access your own status feed, and post new stuffs to your account. In this short series of articles, we’ll re-build it pieces by pieces, starting with a simple widget displaying specific statuses and the public timeline, to adding more complex functionalities like posting messages to your private widget account.

Note that in order to get the authenticated part to work, you will of course need to have a proper Twitter account. Those who don’t know Twitter yet might better understand the widget by learning about the service provided by the Twitter site

Twitter

This series of article are also aimed at introducing UWA development good practices, answering frequent questions and pointing to information in the numerous documentation pages we provide. For this reason, this first part will be quite long, as we will take the time to introduce details and pointers during the process of creating the widget.

Hopefully it will help you getting better at understanding how to work with UWA.

Gathering documentation

Before we start writing any code, we need to understand fully the service we want to UWA-fy. That means gathering information about the service’s ins-and-outs, how it is supposed to handle feeds, connections, users… You cannot expect to build a good widget if you don’t know how to use the service’s resources properly.

Our widget will provide access to Twitter. That service, luckily for us, not only has an ad-hoc API, but also a good documentation to help developers get acquainted with that API.

What we are looking for in this documentation is data feeds that we can access, whether freely or through authentication. At first we will focus on public data - we’ll keep the feeds that require authentication for later.

We quickly learn that Twitter conforms to the REST design principles for a web services, which roughly means it leverages the HTTP protocol’s methods, like GET, POST, PUT, etc. The Twitter feeds are available in XML, JSON, RSS 2.0 and Atom 1.0, respectively through the .xml, .json, .rss and .atom file extensions of the chosen feed.

Twitter provides a handful of public methods, among which are show() which returns a single status, and also public_timeline() which returns “the 20 most recent statuses from non-protected users who have set a custom user icon”. Those two methods are accessible through the following URLs:

http://twitter.com/statuses/show/[status id].[xml|json|rss|atom]
http://twitter.com/statuses/public_timeline.[xml|json|rss|atom]

With this knowledge in hand, we will first build a widget that will only display one specific status. Not really useful as-is, obviously: this is just a way to get us started on how UWA uses feeds.

Building the widget’s skeleton

Instead of starting from scratch, the documentation provides a simple HTML skeleton to which you can add your code. We’ll start from there, section by section. We encourage you to directly copy/paste that skeleton, and to modify it to suit your needs.
As a convention, try to give your widget’s file a meaningful name. For this series, we’ll name it, obviously, twitter.html.

Starting with the file’s HEAD section

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:widget="http://www.netvibes.com/ns/"  >
  <head>

Our file is in XHTML 1.0 Strict, with the usual headers. The only UWA-specific line is the one that points to the Netvibes namespace for the custom widget:preference element.

Adding the metadata

Here’s our modification to the metadata part of the skeleton. Make sure you change every line to properly describe you and your widget.

    <meta name="author" content="Xavier Borderie" />
    <meta name="website" content="http://dev.netvibes.com/blog/" />
    <meta name="description" content="Access Twitter data" />
    <meta name="version" content="0.1" />
    <meta name="keywords" content="twitter" />

    <meta name="apiVersion" content="1.0" />
    <meta name="inline" content="false" />
    <meta name="autoRefresh" content="300" />
    <meta name="debugMode" content="true" />

Building the preferences

If the service you point to accepts variables, you are very much encouraged to allow the user to change them, rather than to simply display the data feed content. Even if the service doesn’t accept variables, you can still let the user decide how many entries he wants displayed, how often to update the content, etc. This is all done in the widget:preferences element.

For now, we simply use Twitter’s show method for now, which displays a single ID based on the ID number we send. We will only provide one preference, with a default value: the ID number the user wants displayed.

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

Preferences are accessible to JavaScript using the widget.getValue(prefName) method - here, widget.getValue('id').

Putting the CSS and JavaScript in place

CSS and JavaScript are to be added in the standard style and script tags. We will only use JavaScript for now, so let’s adapt the skeleton’s code:

    <script type="text/javascript">
      var Twitter = {}

      Twitter.onLoad = function() {
        var url = 'http://twitter.com/statuses/show/'
          + widget.getValue('id') + '.json';
        UWA.Data.getJson(url, Twitter.display);
      }

      Twitter.date = function(date) {
      	var dateArray = date.split(' ');
      	return new Date(
          Date.parse( dateArray[0] + ', ' + dateArray[2] + ' '
             + dateArray[1] + ' ' + dateArray[3] + ' '
             + dateArray[5].substring(0,4) )
        );
      }

      Twitter.display = function(json) {
      	widget.setTitle('Status from ' + json.user.name);

      	var when = Twitter.date(json.created_at);
        var month = when.getMonth()+1;
        month = (month < 10) ? '0'+month : month;

        widget.setBody(
          "<p>From: " + json.user.name + "</p>" +
          "<p>Date: " + when.getFullYear() +'-'+ month
             +'-'+ when.getDate() +' at '+ when.getHours()
             +':'+ when.getMinutes()
             +':'+ when.getSeconds() + "</p>" +
          "<p>Message: " + json.text + "</p>"
        );
      }

      widget.onLoad = Twitter.onLoad;
      widget.onRefresh = Twitter.onLoad;
    </script>

We chose to use the JSON representation of the status’ data. Whatever the data format chosen, we need to know which form it has been given by the service, in order to handle it properly. This can be done by viewing directly the feed using the cURL tool, or simply using your browser, with the full URL of the API method. This will display the data’s content, from which you can learn what are the available data fields.
As for the code itself, the one used above is lifted and heavily adapted from the Ajax Examples pages.

In this example, we are using an alternative function syntax: WidgetName.functionName = function(functionArgs) { ...}. While this might help some developers to group sibling functions under the same notation, it could also bring confusion to others. Fear not, as nothing forces you to use this convention in your code ; you can just as well use the usual syntax: function WidgetName.functionName(functionArgs) { ... } .

If you want your JavaScript code to be launched as soon as your widget is loaded, you need to set the widget.onLoad method, whether by making it point to the JavaScript function to trigger (without the ending (), or else widget.onLoad will be set to that method’s result), or filling its code block with the needed code lines.
widget.onRefresh is the equivalent of widget.onLoad, but is triggered when the widget is refreshed - that is, when its preferences are modified. We here simply set it to our own Twitter.onLoad method.

Twitter.onLoad is set to fetch the JSON feed, using the UWA.Data.getJson method, and directing to the Twitter.display method (again, without the final ()) if the request is successful. The Ajax request is here relaunched every time we change the id preference and validate the preference form.

Because JSON is very easy to handle in JavaScript, the Twitter.display method can be very small, simply putting the right JSON content in the right HTML tag. We’ve therefore added another method, Twitter.date(), that will help us display Twitter’s custom date format in a more readable way.

Adding the static HTML

The HTML code used to display the content can be entirely changed and rewritten through JavaScript & DOM. You can therefore put whatever you wish in here for now, but a good practices is to warn the user that the content is loading, and thus that he may have a few seconds to wait until he sees the whole interface. In this case, we encourage the following:

</head>
<body>
  <p>Twitter is loading ...</p>
</body>
</html>

However, there are times when you’d rather not have to build the whole interface using JavaScript - which will be the case for us when our widget gets more complex. Nothing keeps you from directly setting up the HTML code, maybe hiding it using CSS while the content is loading, and targetting the HTML elements using their unique tagnames/CSS classes and the DOM (remember that getElementById() is not available for now in UWA).

This is it for now. Here is the full code. The next part will deal with full RSS displaying, using public_timeline().

Tags: , , , , , ,

2 Responses to “Building a Twitter widget, part 1: setting-up the code and displaying a single status”

  1. Toby Beresford Says:

    “However, there are times when you’d rather not have to build the whole interface using JavaScript - which will be the case for us when our widget gets more complex. Nothing keeps you from directly setting up the HTML code, maybe hiding it using CSS while the content is loading..”

    This seems to me to be important when keeping code clean by separating view(s) and controller… Please can you do a case study / uwa user manual page that demos best practice for this technique too?

    Thanks

    Toby

  2. PHP-UWA Widget Library | Technik, Gothic und Anderes Says:

    […] Homepage und ist gut dokumentiert. Es gibt Beispiele, ein Code-Skelett mit Erklärung, ein Schritt-für-Schritt Tutorial, ein Forum und sogar ein Cheat-Sheet. Der Einstieg wird einem wirklich so einfach wie möglich […]

Leave a Reply