Documentation: New Widget

What is a widget

A widget is a piece of XHTML2 (with Zaltana extensions) written by a developer which is transformed by Zaltana in to a collection of HTML/CSS/JS resources in the browser to offer the user a particular piece of functionality or display information in a particular way. There are many different widgets in Zaltana ranging from the simple to the complex.

Widget Components

A widget usually consists of any combination of the following resources

  • XSLT
  • CSS
  • JavaScript
  • Images

If you are creating a new widget from scratch you must put it in core this is the zaltana style which all other styles inherit from.

If I wanted to make a new widget called tasty_widget and it used XSLT, CSS, JavaScript and Image files I would arrange the files like this

  • core/xsl/tasty_widget.xsl
  • core/scripts/tasty_widget.js
  • core/css/tasty_widget.css
  • core/images/tasty_widget/images_go_here

Namespacing

All widgets should be namespaced this means your class names used in the XSLT should begin z- e.g.

<a href="http://www.url.com" class="z-popups">the link text</a>

Likewise the JavaScript objects and classes for each function should be namespaced e.g.

z-popups = {
 // methods go here
}

NOTE - The current Zaltana widgets have NOT been namespaced. This should be changed over time.

JavaScript in Widgets

We have chosen to use some important conventions when writing JavaScript for widgets.

WidgetRegistry

All JavaScript widgets must use the widgetRegistry this handles associations between the code for JavaScript widgets and the class names used in the HTML to identify them.

e.g. widgetRegistry makes sure that links.configure method is called when a page containing the popup widget (<a href="some/url" class="popup">text</a>) is loaded.

Objects as namespaces

By using objects as namespaces we can prevent conflicts in the code and have a more logical easier to read coding style.

While older copy and paste scripts looked like this:

var commonSense=null;
var standardsCompliance="50%";
function init(){
  // code
}
function doStuff(){
  // code
}
function doMoreStuff(){
  // code
}

Newer scripts inside tutorials tend to look like this:

awesome={
  commonSense:null,
  standardsCompliance:"50%",
  init:function(){
    // code
  },
  doStuff:function(){
    // code
  },
  doMoreStuff:function(){
    // code
  }
}

Almost all of the JavaScript I've written for various widgets uses the later style.

Fore more info try these links

Alternatively Google for "javascript objects as namespaces"

  • Unobtrusive Scripting Techniques

In the same way that we should keep structure (HTML) and presentation (CSS) separate functionality (JavaScript) should also be treated as a separate layer.

We want to avoid writing inline JavaScript like this.

<a href="javascript:openANewWindow('url');">Click me</a>

In order to do this you are mixing JavaScript and HTML in the output and in the XSLT files which gets messy. It also means we have to write a separate version of the XSLT for styles which are meant to work without JavaScript like the accessible style. Unobtrusive scripting solves these problems and more.

A rough example of how to do this unobtrusively would be like this

Declare your functions in a separate javascript file. Add a class to your HTML tags which the JavaScript can use to identify them using a library like addEvent or YUI.

Make sure you add a register function to your JavaScript code which will add it in to the widgetRegistry

HTML

<a href="url" class="myNewWidget">click me</a>

JavaScript

The JavaScript would then look something like this

var links = {
	register:function(reg)	{
		reg.popup = function(inp){links.configure(inp);};
	},

	configure:function(a) {
			// TODO use add event
			a.onclick=function(){return(links.click(this));};
	},

	click: function(a) {
		var configString = "toolbar=1,location=1,directories=1,status=1,menubar=1,scrollbars=1,resizable=1,width=700,height=550, left=25, top=25";
		window = window.open(a.href,a.href,configString);
		return false;
	}
};
links.register(widgetRegistry);