Initially developped by Google, OpenSocial is “a common API for social applications across multiple websites. With standard JavaScript and HTML, developers can create apps that access a social network's friends and update feeds.”
Netvibes UWA implements the OpenSocial API natively, so that UWA developers can make their widget social easily.
This short documentation is dedicated to the specifis of making OpenSocial work within UWA. A complete guide to OpenSocial API is available from the official OpenSocial website.
Developers can test their OpenSocial-enabled UWA widget using the sandbox site - where they will also be able to test support for their iGoogle gadgets.
<?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> <meta name="author" content="John Doe" /> <meta name="description" content="A descriptive description" /> <title>Title of the Widget</title> </head> <body> <p>Hello world!</p> </body> </html>
This very basic widget lets us see the main characteristics of an UWA widget:
<meta> is used for metainformation (about the widget, the author, etc.) ;<head> also contains the scripting and styling tags, respectively in the usual <script> and <style>.<body> is the main container node - this is where the widget HTML code goes ;In order to work with the OpenSocial API, you need to add the following meta tag:
<meta name="opensocial" content="0.8" />
You can choose any version the OpenSocial API, from 0.6 to 0.8.
A basic OpenSocial-enabled UWA widget should therefore read like so:
<?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> <meta name="author" content="John Doe" /> <meta name="description" content="A descriptive description" /> <meta name="opensocial" content="0.8" /> <title>Title of the Widget</title> </head> <body> <p>Hello world!</p> </body> </html>
Once OpenSocial is enabled in your UWA widget, you can use its JavaScript API as-is, placing the JS code in the <script> tag, and the CSS code in the <style> tag. Both tags are to be place in the <head> tag.
The OpenSocial API is simply an addition to the existing UWA JavaScript framework. In order to work correctly within the Netvibes environment, a UWA widget (and therefore, an OpenSocial-enabled UWA widget) must follow some rules, listed in the UWA documentation. Here are some of the important points:
widget.onLoad() method.
You should not rely on HTML hacks such as <body onload=“xxx();”> in order to launch the JavaScript code: UWA has the adequate method for that. For instance, if your first JavaScript method must be MyWidget.MyFirstMethod(), then you must trigger it with the following code:
widget.onLoad = MyWidget.MyFirstMethod;
If you need to build a whole block, you can:
widget.onLoad = function() { MyObject.MyFirstMethod(); MyObject.MySecondMethod(); }
widget.onLoad = myMethod; is the UWA equivalent to gadgets.util.registerOnLoadHandler(myMethod)
window and document objects, for maximal portability. Most of their methods and properties have been safely moved into the widget object. See the documentation for a full list, or the cheat-sheet. For the same reasons, document.getElementById('xxx') is not recommended: developers should rely on unique classes instead of ids, and target them using widget.body.getElementsByClassName('xxx')[0].widget.log() method to log data in the platform's console (desktop or browser, such as FireBug).widget.log('value i is now = ' + i);
Read the whole UWA documentation to get a better idea of what makes a UWA widget - and how to build an OpenSocial-enabled UWA widget.
UWA implements the OpenSocial API as-is, therefore you should be able to follow the original OpenSocial tutorial and make it work within Netvibes.
For instance, the tutorials's first sample code should work as-is in UWA, like so:
<?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> <meta name="author" content="John Doe" /> <meta name="description" content="A descriptive description" /> <meta name="opensocial" content="0.8" /> <title>Title of the Widget</title> <script type="text/javascript"> MyWidget = {}; /** * Request the OWNER and OWNER's friends. */ MyWidget.request = function() { var idspec = opensocial.newIdSpec({ "userId" : "OWNER", "groupId" : "FRIENDS" }); var req = opensocial.newDataRequest(); req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER), "get_owner"); req.add(req.newFetchPeopleRequest(idspec), "get_friends"); req.send(MyWidget.response); }; /** * Parses the response and generates html to list the names of the owner and * his or her friends. * * @param {Object} dataResponse Friend information that was requested. */ MyWidget.response = function(dataResponse) { var owner = dataResponse.get('get_owner').getData(); var friends = dataResponse.get('get_friends').getData(); var html = 'Friends of ' + owner.getDisplayName(); html += ':<br><ul>'; friends.each(function(person) { html += '<li>' + person.getDisplayName() + '</li>'; }); html += '</ul>'; // document.getElementById('message').innerHTML = html; // original sample code widget.body.getElementsByClassName('message')[0].innerHTML = html; // UWA equivalent }; // Execute the request function when the application is finished loading. //gadgets.util.registerOnLoadHandler(request); // original OpenSocial handler widget.onLoad = MyWidget.request; // UWA equivalent </script> </head> <body> <div id="message" class="message">Loading...</div> </body> </html>
Depending on wether you have friends or not on the sandbox, the result might look like this:
From there on, you can certainly imagine the numerous uses for social widgets! :)
While the OpenSocial code itself works as-is, some slight adaptation have to be made to work seamlessly within the UWA environment. These are mostly harmless, and some are already documented in the code's comments.
Functions were put into a global object: declaring functions in the form function request() { … } means that they are really part of the document object, which in UWA is not recommended for portability issues (same for window). In order to call these functions cleanly, we therefore have to make them methods of a local object, which will also contain de variables.
So, instead of having…
function request() { ... } function response(dataResponse) {
…we need to declare a JS object (here named MyWidget)…
MyWidget = {}; MyWidget.request = function() { ... } MyWidget.response = function(dataResponse) {
…and the function calls have to be harmonized in the code.
The original sample code uses Google Gadget as its container. That container uses the following onLoad handler:
gadgets.util.registerOnLoadHandler(callback);
Whereas UWA uses the following onLoad handler:
widget.onLoad = callback.
Therefore, we change the code from…
gadgets.util.registerOnLoadHandler(request);
…to…
widget.onLoad = MyWidget.request;
(note that request() is now a method of our local object)
As said earlier, document is not of recommended use within UWA. Therefore, this…
document.getElementById('message').innerHTML = html;
…has to be replaced by a UWA extension, getElementsByClassName()…
widget.body.getElementsByClassName('message')[0].innerHTML = html;
…along with the target element receiving a unique classname:
<body> <div id="message" class="message">Loading...</div> </body> </html>