Wyatt

brings mustache into your Titanium application

Download latest version (v0.1.0)

Introduction

Since Titanium helps us writing complex mobile applications in Javascript, the pain has always been to describe views. Alloy had to solve this problem with the brand new XML approach plus its TSS style definition. For me as for many other Titanium developers, it was quite something and I was prepared to migrate all my former code to Alloy.

The Alloy concept has been a bit frustrating for me. I'm an anti-precompiler. I think precompiling is a fail in a compilation process. I couldn't stand it in C, I don't like CoffeeScript, so I wasn't happy to see that Alloy came with its precompilation system behind a big MVC machine.

Wyatt is not meant to replace Alloy.

In fact, the development pattern is completely different : Alloy is a framwork, Wyatt is a simple template&query engine, that's it. The rest of the application : your MVC choice if you want MVC, your libs, your db manager ... I won't code your application, you're the boss here.

Getting Started

Write your index.yat file


{
  "el": "window",
  "options": {
    "fullscreen": true,
    "backgroundColor": "white"   
  },
  "tree": [
    {
      "el": "label",
      "options": {
        "text": "{{message}}"
      }
    }
  ]
}
          

Then render it in your app.js file


var wyatt = require('wyatt');

// Generates the UI
var yat = wyatt.render('index.yat', {message: 'Hello World !'})
// Finds and open the window
yat.first({el: "window"}).open();
          

Wyatt API

wyatt.render(path, context)

Returns a YAT Document from a template path and a given context.

wyatt.yat(description)

Returns a YAT Document from a given description (Javascript Object).

wyatt.el(name)

Returns an Element constructor from its name (eg: 'view', 'button' ...).

wyatt.register(name, constructor)

Registers a constructor with the given name. The new name can be used next in a YAT Document.

YAT Document

Wyatt read YAT Documents to render the element tree.

Syntax

YAT syntax is basicaly JSON with some specials keys.

Mustache basics

Mustache is the template processor used to generate the element tree from a given context.

The logic-less system is fast to process and very adapted for mobile development.

In a nutshell :

As the processor used is Handlebars (like was Wyatt Earp mustache),

You can learn more here : handlebarsjs.com

Making Queries

When a document is rendered, the first thing you'll need to do is retrieve the elements to manipulate them.

Queries are made for that.

The methods listed here are callable from a YAT Document Object Model (generated by wyatt.render)

yat.where(query)

Retrieve the list of elements in the document where the query match.

The query parameter is an object using like a filter.

The keys in the filter can be "el" (to filter by element name) or anything defined in the YAT Document.

query-example.yat :


{
  "el": "view",

  "tree": [
    {
      {{#persons}}
      {
        "el": "label",
        "job": "{{job}}",
        "options": {
          "text": "{{name}}"  
        }
      }
      {{/persons}} 
    }
  ]
}
          

app.js :


var wyatt = require('wyatt');

// Generates the UI
var yat = wyatt.render('query-example.yat', {
  persons: [
    {name: "John Smith", job: "developer"},
    {name: "Stewart McKay", job: "developer"},
    {name: "Bob White", job: "manager"},
  ]
});

// Finds all the developers and change their color
yat.where({el: "label", job: "developer"}).forEach(function (el) {
  el.attr('color': 'red');
});
          

yat.first(query)

Same as above but return only the first element.

Sub Queries

Elements have their own YAT Document Object Model for their own tree.

So they can be used as query proxies.

subquery-example.yat :


[
  {
    "el": "view",
    "food": "fruits",
    
    "tree": [
      {{#fruits}}
      {
        "el": "label",
        "options": {
          "text": "{{name}}"  
        }
      }
      {{/fruits}} 

    ]
  },
  {
    "el": "view",
    "food": "vegetables",
    
    "tree": [
      {{#vegetables}}
      {
        "el": "label",
        "options": {
          "text": "{{name}}"  
        }
      }
      {{/vegetables}} 

    ]
  }

]
          

app.js :


var wyatt = require('wyatt');

// Generates the UI
var yat = wyatt.render('subquery-example.yat', {
  fruits: [
    {name: "Peach"},
    {name: "Apple"},
    {name: "Cherry"},
  ],
  vegetables: [
    {name: "Endive"},
    {name: "Letuce"}
  ]
});

// Finds all the vegetables and change their color
yat.first({id: "vegetables"}).where({el: "label"}).forEach(function (el) {
  el.attr('color': 'green');
});
          

Element

Elements (or view elements) are Titanium UI wrappers. This pattern is inspired by jQuery.

You'll get an element instead of the direct UI, but Why ?

An element will have a bunch of shorcuts and useful methods to helps you manipulating UI attributes and events.

However, elements keep the UI intact and you can still retrieve it with el.ui attribute

.ui

ui attribute is a access to the original Titanium UI object (eg Ti.UI.View)

.attr(key, value)

A single way to set parameters. Looks first for a setter (eg: 'color' -> ui.setColor). If the setter doesn't exist, use a simple patch

Can be chained. Example :


yat
  .first({id: 'something'})
    .attr('color', 'white')
    .attr('width', '50px')
    .attr('opacity', 0.5)
          

.trigger(event, data)

A proxy method to ui.fireEvent

.on(event, callback)

A proxy method to ui.addEventListener

.off(event, callback)

A proxy method to ui.removeEventListener

Custom Element

Any element can be extended and used in the YAT document

The process : retrieve the element by its name, extend it, override the create method.

Example :


var wyatt = require('wyatt');

wyatt.register('redbutton', wyatt.el('button').extend({

  create: function (options) {
    options.backgroundColor = 'red';
    wyatt.el('button').prototype.create.apply(this, [options]);
  }

}));

//  Now 'redbutton' can be used in a YAT Document.