Introducing MooTools Templated

One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating:

The problem with creating elements programmatically within widgets is that doing so means your class becomes inflexible. What if you want one of the elements to have a specific CSS class? What if you want one of the elements to be a DIV instead of a SPAN? What if you don't want one or more of the elements generated by the class? You would need to extend the class and override the method that created all of the elements. Yuck.

User Reliance

The second way to create UI-driven classes is to rely on the developers using your classes to provide the correct elements to the class in the correct hierarchy. This could include providing elements to the initialize method of a class' instance. I dislike this method for complex widgets because there's too much reliance on the user to figure out what elements your class needs.

The Solution: MooTools Templated

Templated is a MooTools mixin class which creates elements for classes using a string-based HTML template which may included embedded attach points and events. Templated is very much inspired by the Dojo Toolkit's dijit._Template resource, which has been tried, tested, and proven in Dojo's outstanding Dijit UI framework. Let's explore what Templated is and how to use it!

Templates and Terms

Before using the Templated mixin, it's important to understand a few concepts and terms. Take the following template for example:

Within the template you'll see attach points, attach events, and props. Attach points are named properties which will be attached to the widget instance and map to the given node within the template. Attach events are key (event type) => value (event handler) mappings separated by a colon. Multiple attach points can refer to the same element, and an elements may have many attach events; both a comma-separated. Props are configuration properties for the node's given instance if the node is mean to be a widget itself. Props are written in JSON-style syntax and property keys should match the element options; the options and props (if they exist) are merged.

The following snippet should provide a bit more clarity as to what each mean:

Attach points, events, and props are all very simply to use but provide an essential function for maximum customization in UI widget templating. Templated also looks for string substitution (String.substitute) opportunities, allowing you to add basic variables within your templates.

Using MooTools Templated

To use Templated within MooTools, add Templated to your class' Implements array:

Implements: [Options, Templated]

With Templated available within the class, a few more options are available within the class:

template: The string HTML template for the class, including attach points, events, props, and subwidgets.

templateUrl: The URL to the widget's template if it's external. A basic Request will be sent to retrieve the widget if not yet cached.

element: The element which the widget's domNode will replace.

widgetsInTemplate: If true, parses the widget template to find and create subwidgets. Inline attach points and attach events are added to the parent widget, not the subwidget.

propertyMappings: An object which contains custom property mappings for the widget.

defaultPropertyMappings: An object with default, fallback property mappings for the widget. Property mappings included ID, style, and class, which these properties are carried over from the base element to the domNode.

When you desire for the template to be parsed and nodes to be created, calling this.parse() will accomplish that task. You will usually want to call this method within the initialize method after the options have been set:

Your UI widget has been created with flexibility and ease of use in mind!

Templated Events

Templated provides stub methods along the way so code can be executed at different points within the creation of the widget:

postMixInProperties: Fires after the options and widget properties have been mixed.

postCreate: Fires after the widget nodes have been created but before the nodes are placed into the DOM

startup: Fires after the widget has been created and is placed into the DOM

These methods have proven to be useful within the Dojo Toolkit.

Templated Helpers

Templated also provides two essential widget helpers: Element.parse and document.widget. Element.parse allows for declarative (node-based) widget creation. So if your page contains nodes with data-widget-type properties, you can use the parse method of elements to find widgets and subwidgets. Take the following HTML:

Running the following JavaScript snippet would parse the page, find the DIV, and create a widget from it!

document.body.parse();

The document.widget method accepts a DOM node and returns the widget object which it represents:

var myWidget = document.widget("qHolder2");

Being able to retrieve a widget based on a node is very helpful in debugging your application.

Realistic Usage

One of the popular UI plugins I've created is LightFace, the Facebook-like lightbox. Unfortunately LightFace falls victim to the "new Element Madness" because of the complexity of the widget structure. Many people were unhappy about its table-based structure (which accommodated for IE6) and wanted a DIV-based structure...and with Templated, you can make that happen.

BETA!

Get Templated!

The ability to apply this level of control to widget templating is amazing. Dijit's use of _Templated help makes the UI framework the best available for any JavaScript framework. Please consider using Templated for your UI work, especially if your components are open source or maintained by a team. Have fun with your UIs!

Google Plus provides loads of inspiration for front-end developers, especially when it comes to the CSS and JavaScript wonders they create. Last year I duplicated their incredible PhotoStack effect with both MooTools and pure CSS; this time I'm going to duplicate...

The <canvas> element has been a revelation for the visual experts among our ranks. Canvas provides the means for incredible and efficient animations with the added bonus of no Flash; these developers can flash their awesome JavaScript skills instead. Here are nine unbelievable canvas demos that...

The jQuery homepage has a pretty suave tooltip-like effect as seen below:
The amount of jQuery required to duplicate this effect is next to nothing; in fact, there's more CSS than there is jQuery code! Let's explore how we can duplicate jQuery's tooltip effect.
The HTML
The overall...

At last week's Mozilla WebDev Offsite, we all spent half of the last day hacking on our future Mozilla Marketplace app. One mobile app that recently got a lot of attention was Instagram, which sold to Facebook for the bat shit crazy price of one...

Discussion

Be sure to send me suggestions and bug reports when you start using it heavily.

Andrea

Oh well, it’s a very useful thing :)
I’d like to have a HUGE repository with base and custom widget….
a community widget repo!

Amitay Horwitz

Definitely a needed addition. Thanks David, will be checking it out!

Roark

Hey David,

Great article and something I really want to get my head around at the moment I am so far away from understanding whats going on its scary!

Why in your demo does the UIWidgetButton not take on the default label "Default Submit Option"?

I changed the UIWidget template (button part) to data-widget-props='label:\"{label}\"
and it worked for the first sample but not when we load the external template. Do you know why?

Roark

Please ignore previous question, the answer was pretty simple, add data-widget-props="label:'{label}'" to the node calling UIWidget (in the external html file) and in turn it will be available when calling UIWidgetButton in the UIWidget template

Thanks

Roark

David, could you please tel me why Templated doesn’t work as ecpected with mooTools 1.4,
It’s not keeping class names specified in the template string.

Georg

Hi David,

your template engine sounds great! Which version of mootools is required? Is it already “stable” / developed actively?

Continue this conversation via emailGet only replies to your comment, the best of the rest, as well as a daily recap of all comments on this post. No more than a few emails daily, which you can reply to/unsubscribe from directly from your inbox.