Universal Widget API :
How to build
multiplaform widgets
Xavier Borderie / netvibes
http://dev.netvibes.com
ParisWeb 2007 workshop
Saturday, November 17th, 2007
What are widgets
• Small, specialized applications (mostly)
• Available through the browser: Netvibes,
iGoogle, Live.com,YourMinis...
• Available through an installed engine:Vista
Gadgets, Apple Dashboard,Yahoo! Widgets,
Opera...
Netvibes’ thinking when
creating UWA
• MiniAPI is doing quite well
• 1000 modules since May 2006
• Positive feedbacks from the community
• No de-facto standard
• Each site/engine uses its own format
• W3C’s specification is still in its infancy
(working draft)
What UWA promises
• Works on the most popular platforms,
without any change to the original file
• Today: Netvibes, iGoogle, Live.com,
Opera, Apple Dashboard, Windows Vista,
Yahoo! Widgets
• Works just like MiniAPI, in a stricter way
• Easy to learn thanks to proven standards:
XHTML/XML, JavaScript/Ajax, CSS
UWA basics
• One static XHTML file, using well-formed
XML
• UTF-8 encoding
• Netvibes namespace a must:
xmlns:widget=“http://www.netvibes.com/ns/”
Presenting the basic
skeleton
• http://dev.netvibes.com/files/uwa-skeleton.html
• Starting point for most of the developers,
through copy/pasting
• Skeleton generator is in the testing phase...
Skeleton 1 :
XHTML headers
• Nothing new here...
• ...just don’t forget the Netvibes namespace
<?xml version=quot;1.0quot; encoding=quot;utf-8quot;?>
<!DOCTYPE html PUBLIC quot;-//W3C//DTD XHTML 1.0 Strict//ENquot;
quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtdquot;>
<html xmlns=quot;http://www.w3.org/1999/xhtmlquot;
xmlns:widget=quot;http://www.netvibes.com/ns/quot; >
<head>
<title>Title of the Widget</title>
<link rel=quot;iconquot; type=quot;image/pngquot;
href=quot;http://www.netvibes.com/favicon.icoquot; />
Skeleton III :
emulation files
• Optional but very useful when testing in
Standalone mode
<link rel=quot;stylesheetquot; type=quot;text/cssquot;
href=quot;http://www.netvibes.com/themes/uwa/style.cssquot; />
<script type=quot;text/javascriptquot;
src=quot;http://www.netvibes.com/js/UWA/load.js.php?
env=Standalonequot;></script>
Skeleton IV :
UWA preferences
• UWA-specific tag set
• Bad: doesn’t work well with the W3C
XHTML validator
• Good: makes for more portable preferences
<widget:preferences>
<preference name=quot;urlquot; type=quot;textquot; label=quot;URLquot;
defaultValue=quot;http://feeds.feedburner.com/NetvibesDevBlogquot; />
<preference name=quot;passquot; type=quot;passwordquot; label=quot;Passwordquot; />
<preference name=quot;displayImagesquot; type=quot;booleanquot; label=quot;Display images?quot;
defaultValue=quot;truequot; />
<preference name=quot;limitquot; type=quot;rangequot; label=quot;Number of items to displayquot;
defaultValue=quot;10quot; step=quot;1quot; min=quot;1quot; max=quot;25quot; />
<preference name=quot;categoryquot; type=quot;listquot; label=quot;Categoryquot;
defaultValue=quot;1stquot; onchange=quot;refreshquot;>
<option value=quot;allquot; label=quot;allquot; />
<option value=quot;1stquot; label=quot;First categoryquot; />
<option value=quot;2ndquot; label=quot;Second categoryquot; />
<option value=quot;3rdquot; label=quot;Third categoryquot; />
</preference>
<preference name=quot;searchquot; type=quot;hiddenquot; defaultValue=quot;quot; />
</widget:preferences>
Skeleton VI :
End of file
• The body can be pre-filled or completely
empty: its content is free since the DOM can
update it at any time
• Data are loaded using JavaScript and placed
in the body using the DOM
</head>
<body>
<p>Loading...</p>
</body>
</html>
Using CSS
and JavaScript
• Works just like in a classic HTML file:
<script> and <style>
• Refrain from using external files: put
everything in the widget
• CSS: try prefixing every rule with class
named after the widget, .myWidget p { ... }
• CSS: target with classes rather than ids
• JS: put every method/variable in an object
named after the widget, var MyWidget = {};
Fliptext
• http://nvmodules.typhon.net/maurice/
fliptext/
• Entirely made with just HTML, CSS et JS - no
external calls
• Adapted in UWA from the original code, to
be found at: http://www.fliptext.org/
widget.onLoad = function() {
for (i in Flip.table) {
Flip.table[Flip.table[i]] = i
}
out = '<textarea></textarea><p><button>flip <img
src=quot;http://nvmodules.typhon.net/maurice/fliptext/refresh.pngquot;
alt=quot;Flipquot; /> dılɟ</button></p><textarea></textarea>';
widget.setBody(out);
var bt = widget.body.getElementsByTagName('button')[0];
var textareas = widget.body.getElementsByTagName('textarea');
bt.onclick = function(){
var result = Flip.flipString(textareas[0].value.toLowerCase());
textareas[1].value = result;
}
}
Fireplace
• http://nvmodules.typhon.net/maurice/
fireplace/index.html
• Demonstrating the possibility to use Flash
• The widget generates the HTML using
JavaScript, but you can directly place the
<object> tag within the widget’s body, and
never use JavaScript
• You can also directly submit your SWF to
Ecosystem, which will wrap it in a UWA
container for you
Build a Zorglangue widget
from the Fliptext widget
• http://ndiremdjian.free.fr/pics/zorglangue.htm
• Same CSS and widget.onLoad() as in Fliptext
• Just place the linked page’s JavaScript in a
Zorglub object.
The final Zorglangue
• http://nvmodules.typhon.net/maurice/
zorglub/
• Compare the code with Fliptext:
http://nvmodules.typhon.net/maurice/
fireplace/index.html
UWA’s JavaScript
method and properties
• Refrain from using or
document window
• Replace with
document.getElementById(‘id’)
widget.body.getElementsByClassName(‘class’)[0]
• HTML elements are only extended when
created using widget.createElement(). You can
extend them by hand:
var foo = UWA.$element
(widget.body.getElementsByClassName
(‘bar’)[0];
foo.setStyle(‘backgroundColor’, ‘red’);
UWA’s JavaScript
method and properties
• Most of the methods and properies have
been moved document and window, into two
UWA-specific objects: widget et UWA.
• widget: usual methods found in JavaScript
frameworks
• UWA: mostly only used for UWA.Data, which
contains the Ajax methods
• See the UWA cheat-sheet :)
Ajax methods
• 4 quick methods:
• UWA.Data.getText(url, callback);
• UWA.Data.getXml(url, callback);
• UWA.Data.getJson(url, callback);
• UWA.Data.getFeed(url, callback);
• All are built upon the master one:
• UWA.data.request(url, request);
UWA.Data.request
• Allows you to make more complex queries:
POST + parameters, authentication, cache
handling...
• UWA.Data.request(url, request) :
• request = { method:’post’,
proxy:’ajax’, cache:3600,
parameters:’lastname=Bond&id=007’,
onComplete:MyWidget.display };
Practical examples:
Getting images out of a feed: FFFFOUND
Handling a feed: Skyblog
getText and parsing: DeMets
getText and parsing: LinkedIn
Getting images out of a
feed: FFFFOUND
• http://nvmodules.typhon.net/maurice/uwa-
ffffound/
• JS: getting the feed with getFeed(), extracting
the image links (<link> from the JSON feed
format), HTML code built on the fly
• CSS: placing the elements
• JSON Feed Format: http://dev.netvibes.com/
doc/uwa_specification/
uwa_json_feed_format
Handling RSS/Atom:
Skyblog
• http://nvmodules.typhon.net/maurice/
skyblog/
• Preferences: blog’s name and number of
articles to display
• JS: parsing the JSON feed, building the HTML
code using the DOM rather than in a string
• Nota: use of the limit preference
• Nota: UWA.Utils.setTooltip()
getText and parsing :
DeMets
• http://nvmodules.typhon.net/maurice/uwa-
demets/
• getText on a custom PHP script (UTF-8
conversion)
• A few RegExps to remove most of the
useless content
• finally getting and displaying the restaurant’s
menu
getText and parsing :
LinkedIn
• http://florent.solt.googlepages.com/linkedin-
pretty.html
• getText directly on the URL to be parsed
• Display the chosen section (via preference),
with a bit of RegExps to simplify/manipulate
the content
Models and controlers
• To better fit in the platform’s theme/style
• To ease the conception of some common
applications/needs
Models
• CSS classes
• Data grid
• E-mail list
• Feed list
• Rich list
• Thumbnailed list
Practical examples:
getFeed and FeedList: RSSReader
JSON request and Pager: Twitter
getJson and TabView: TwitterKing
getText parsing and TabView+Pager+...:
Rugby World Cup
RSS Reader
• http://www.netvibes.com/api/uwa/examples/
rssreader.html
• getFeed translate any kind of feed into an
internal and normalized JSON format
• http://dev.netvibes.com/doc/
uwa_specification/uwa_json_feed_format
• From there on, retrieving the data in
JavaScript is just a matter of knowing what’s
where in the JSON feed
TwitterKing
• http://www.my-widget.com/
twitter_widget.html
• Just like the previous Twitter widget, but
overcharged with any possible API call and
UWA controler :)
Rugby World Cup
• http://nvmodules.typhon.net/romain/
rugbyworldcup/
• getText directly on a third-party URL
• Code parsing, RegExp, recomposition of the
original links, Pager, TabView... the whole
shebang
Thank you!
• http://dev.netvibes.com
• http://dev.netvibes.com/doc/
• http://dev.netvibes.com/forum/
• http://dev.netvibes.com/blog/
• http://eco.netvibes.com
• We are always hiring! :)
http://dev.netvibes.com/doc/jobs