Back to my page

Developer Blog



Converting a MiniAPI module to a UWA widget (part 2)

It takes more than just updating the emulation files’ URLs to turn a MiniAPI module into a fully working UWA widget. In the first part of this series of articles, we saw that many others section of the HTML code itself need to be upgraded, and the documentation already indicates which MiniAPI function calls have been deprecated, and which have been updated to the UWA standard of quality.

Still, this is only enough if the original MiniAPI module is pretty basic, featuring an image, a simply form or a Flash animation. More advanced MiniAPI require more advanced changes, obviously.

Continuing on our mission to reread the original (and deprecated) MiniAPI tutorial into proper UWA code, this second part focuses on Step #6, “Configuration forms”, and its MiniAPI sample code, which expands the “Hello World” sample with said configuration code.

As a side-note, you’ll notice that between the first part and this second part, we skipped steps #3 to #5 of the MiniAPI tutorial. Basically, Multiple Pages are to be replaced by the Pager or the TabView control depending on the initial usage, Markup remains strict XHTML, and Classic Forms will get a part of its own later.

Building a configuration form, MiniAPI-style

(please note the the following code is deprecated MiniAPI code, and will NOT work as expected in a UWA widget)

In order to take into account user settings, MiniAPI used regular forms with a specific configuration class as an attribute. That form was rendered into a widget-specific (and initally hidden) Edit area. Each input value was saved into Netvibes’ server, so that next time the user logged-in, her settings were still there.

Here is the sample’s configuration form, located right in the body part of the file:

<form class="configuration" method="post" action="">
  <label>Name :</label>
  <input name="name" type="text" value="" />

  <br />

  <label>Surname :</label>
  <input name="surname" type="text" value="" />

  <input type="submit" value="ok" />
</form>

MiniAPI made clever use of XHTML and JavaScript/CSS possibilities so that the user didn’t have to learn a new type of form: it was just a regular form with a specific attribute, which MiniAPI used to render it all correctly, seamlessly.

However, that proved to be not portable enough for UWA’s unversality claim. So constrains had to be added, XHTML turned into XML, and configuration form into preference form…

Building a preference form, à la UWA

Here is the exact equivalent of the above MiniAPI configuration form, once rewritten to respect the UWA preference norm:

<widget:preferences>
  <preference type="text" name="name" label="Name"
    defaultValue="" />
  <preference type="text" name="surname" label="Surname"
    defaultValue="" />
</widget:preferences>

This use of XML within XHTML is made possible by the obligatory Netvibes namespace:

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:widget="http://www.netvibes.com/ns/"  >

There are many obvious and less-obvious differences, which we will list here:

  • the whole block of code is placed in the head section of the widget’s file - not in the body anymore
  • the whole behavior is handled by UWA - no need for class, method or action attributes anymore
  • attributes are case-sensitive, ie. defaultValue will work, defaultvalue won’t.
  • once rendered…
    • …the label’s final semicolon is automatically added by UWA - no need to add it anymore
    • …each preference sits on its own line - no need for a br separator anymore
    • …the form’s submit button is automatically added
  • in exchange of portability, UWA preferences are not as easily customizable as MiniAPI configuration forms. Usual custom elements have been moved to normalized meta tags, such as author and website
  • preferences are still saved on the Netvibes server (or in the user cookie, depending of the platform)

Having the ability to render a pretty form is only one part of the trip: we also need to be able to retrieve these settings in order to use them in the widget…

How MiniAPI modules accessed configuration settings

Contrary to UWA, MiniAPI modules are not suggested to use only one static files: multiple files and server-side code could be used for more advanced purposes, one of them being configuration forms.

Here is the body section of the MiniAPI sample module, minus the previously seen configuration form.

<?php if (empty($_COOKIE['name'])) { ?>

<p>Module is not configured. Please edit it.</p>

<?php } else { ?>

<p>Name :
  <?php echo htmlspecialchars($_COOKIE['name']) ?></p>

<p>Surname :
  <?php echo htmlspecialchars($_COOKIE['surname']) ?></p>

<?php } ?>

Since the module is a PHP file, you cannot see the whole code by looking at the file’s source. The complete code is available in the tutorial.

Configuration forms relied on the user’s cookie to save and retrieve the module’s settings, and therefore the module needed cookie-handling code to make use of them. This sample uses PHP, but any server-side language is possible as long as it is available on the module’s hosting server and as the language supports cookie methods.

The code is pretty easy to follow:

  • if the cookie doesn’t contain anything in its “name” value, ask the user to fill the configuration form
  • if the cookie does contain something in its “name” value, we suppose it does too for the “surname” value, and we thus display both values

Note that the settings were also stored in the Netvibes server from the moment they were set, and were made available through the getValue(name) JavaScript method. Settings could also be changed programmatically using the setValue(name, value) JavaScript method.
Using these JavaScript methods rather than server-side cookie-handling ones means the developer had to rely on DOM method to update the body’s content with new values. This is longer to put into place, but is cleaner since it clearly separates content (body) from behavior (moved into script).

Because using JavaScript/Ajax/DOM on static files is cleaner that including server-side code within the module’s body section, this is the recommended with UWA…

How UWA handles preferences

UWA widgets can still make use of multiple files and server-side languages such as PHP, but since this have been prone to errors, we now recommend to use one single static file, use DOM methods to access and update HTML elements, and Ajax methods to get and set server data - most presumably by targeting an external server-side script.

JavaScript methods, then. The MiniAPI’s configuration methods have been put into the new UWA widget object:

  • widget.getValue(name): retrieves the preference’s value as a string
  • widget.getBool(name): retrieves it as a boolean value (true/false)
  • widget.getInt(name): retrieves it as an integer value (number)
  • widget.setValue(name, value): updated the preferences with a new value

Converting the MiniAPI sample therefore requires us to add a script section for the behavioral code:

<script type="text/javascript">
widget.onLoad = function() {
  if ( true === (
      widget.getBool('name') && widget.getBool('surname') ) ) {
    var html = "<p>Name: " + widget.getValue('name') + "</p>";
    html += <p>Surname: " + widget.getValue('surname') + "</p>";
    widget.setBody(html);
    }
  }
</script>

<body>
<p>The widget is not configured. Please edit it.</p>
</body>

In this update of the original code, the “Please edit” text is in place and displayed by default. If both the name and surname values happen to be filled, then the whole body section is replaced with the generated code (the html variable), using the widget.setBody method. The JavaScript is launched as soon as the widget is loaded, thanks to the obligatory widget.onLoad method.

That is basically it for transitioning from MiniAPI configuration forms to UWA preferences. Don’t forget the Netvibes namespace, remember to use the correct preference type instead of just using text, and you should be safe.

Next part of this series will see us dive into Ajax requests, and how MiniAPI and UWA differ and agree…

Tags: , , , , ,

Leave a Reply