| Version 12 (modified by celso, 6 years ago) |
|---|
The Renderer's anatomy
This document provides simple instructions and a skeleton to build a Rendering Widget (ie: A Widget that displays a list of posts from an RSS feed).
SAPO::Widget namespace
This is where all the Widgets live. Each application's Widget should have it's own class and it's own method. For instance, Widgets for the SAPO Tags service are all implemented in the SAPO::Widget.Tags class.
What's a Widget ?
We call a Widget, something that takes a data feed (ie: an RSS feed), manipulates the data and presents the information dynamically that's rendered in the user's Web browser. Widgets can either be static or have user controls (ie: A photo album Widget can have previous and next buttons).
Basics
SAPO's Widget classes are build on top our own library. These classes often depend on other classes, depending on the functionality offered.
We can divide the Widget into 3 layers:
- The data layer (where you get the data from)
- The control layer (how you manipulate the data)
- The presentation layer (how you present the data, and draw the widget)
Data layer
Data is passed to Widgets as JSON arrays. These JSON arrays are often transformed RSS feeds. Our Webservices infrastructure provides real-time RSS-to-JSON transformations so we can have JSON arrays from any kind of RSS feed we know. This is an example JSON feed just transformed from it's original RSS feed.
Out library provides a method SAPO::Widget.Parser->jsonRSS2 to parse an JSON-RSS structure into something more easy to handle. Many widgets use it.
Control layer
This is something we're still working on. We're adopting the Opensearch standard.
Many control features use AJAX models but may also be simple object navigation functions (ie: next and previous photo from an already loaded photolist object).
Presentation layer
We present data by writing directly into the DOM tree and using CSS to manipulate styles.
CSS styles are dynamically set in runtime (ie: they can, but are usually not defined in the webpage source) using the CSS-JSON approach.
Our library provides a method SAPO::Utility.CSS->set to set the CSS styles from a CSS definition in JSON.
Using dynamic CSS, we have full control over the Widget's presentation and we can provide input options to the Widget which may change the CSS styles immediately and accordingly to logical or mathematical operations.
Also, it's the perfect solution for our Snippets.
Hands on
Writing our Hello World widget under the SAPO::Widget.Hello class.
The skeleton
This is the skeleton file for our Hello World widget.
This creates the SAPO::Widget namespace if not already created.
if(!SAPO.Widget || typeof(SAPO.Widget) == 'undefined') {
SAPO.namespace('Widget');
}
This block does two things:
- Creates a namespace for our Exceptions engine log messages.
- Calls the class initializer with this.init()
SAPO.Widget.Hello = function(options)
{
if(SAPO.Exception && typeof(SAPO.Exception) != 'undefined') {
this.exception = new SAPO.Exception('SAPO::Widget.Hello');
} else {
this.exception = false;
}
if(options != 'undefined') {
this.init(options);
} else {
this.init({});
}
};
This is the tipical class init. It has input options passed as JSON. These options may have defaults or not.
The other important thing the init() section does is to automatically create an unique object name for it's instance.
This may seem silly at first sight but it's important if you have to invoke the same Widget class many times in the same page. There's not reason why you should want to do this too but again, it's one of our magic Snippets's requirements, so no harm done.
SAPO.Widget.Hello.prototype = {
init: function(options)
{
options = Object.extend({ // default options
instance: false
}, arguments[0] || {});
this.options = options;
// get an handler for this instance - eval hack
if( this.options.instance === false ) {
this.options.instance=Math.round(10000*Math.random());
var cmd='hello'+this.options.instance+'=this';
eval(cmd);
}
},
TO CONTINUE
Attachments
- mapwidget.png (42.3 KB) - added by celso 6 years ago.
