haiku.js

Fork me on GitHub

Haiku makes DOM trees so simple to generate, I think you'll like it.

Haiku is a lightweight replacement for the standard DOM method of creating new HTML structures, when you don't want or need the overhead of a full-blown templating system like Handlebars. Its syntax (and inspiration for its name) comes from the popular Zen Coding abbreviation engine, which, in turn, is inspired by the CSS selectors specification.

Know CSS? Then you're about 2 minutes away from knowing Haiku. ;)


Installation

Haiku is packaged as an AMD module, but it's dependency-free, so it's simple to install: just drop it in your root JavaScript folder, and require away:

require(["haiku"], function(haiku) {
    document.body.appendChild( haiku.expand("section#main+aside#related") );
});

Basic Usage

Haiku.create("form.center.hbox-layout"); Returns the DOMNode for the entered expression.
Note: if the expression evaluates to more than one top-level node, only the first will be returned. If you need to create multiple nodes at the top level, use expand instead.
Haiku.expand("div.body+footer"); Returns a DOM DocumentFragment, which can be appended just like a DOMNode.
Haiku.expand("div.body+footer", null, true); Instead of a DOM DocumentFragment, returns a string of raw HTML, which can be injected via setting the innerHTML property of a target node.

Data Expansion

Haiku employs two methods for injecting dynamic data into an output stream: expansion and binding.

Expansion happens once, at evaluation time, and is suitable for simple data interpolation to a static output:

Given template tmpl:
tmpl = "a[href=e$id;]{$surname;, $firstName;}"
and object employee:
employee = {
    firstName: "John"
    , surname: "Smith"
    , id: 12345
};
Haiku.create(tmpl, employee) results in: <a href="e12345">Smith, John</a>

Data binding, which allows refreshing of bound values, subtemplates, and conditional logic, will be discussed below.


Operators

ID Operator: “#”

Specifies the HTML ID for an element (ignores multiple operands; an element can only have one ID)

div#main <div id="main"></div>

Class Operator: “.”

Specifies the class for an element (multiple operands allowed)

blockquote.fancy.gothic <blockquote class="fancy gothic"></blockquote>

Child Operator: “>”

Makes the following element a child of the preceding one

ul>li <ul>
  <li></li>
</ul>

Sibling Operator: “+”

Makes the following element a sibling of the preceding one

div>p#intro+p#main <div>
  <p id="intro"></p>
  <p id="main"></p>
</div>

Aunt Operator: “<”

Makes the following element a sibling of the preceding one's parent (i.e goes up one level in the tree)

header>h1<section.main <header>
  <h1></h1>
</header>
<section class="main"></section>

Text Operator: “{ }”

Specifies the contents of a child text node

p>{A }+em{simple}+{ example} <p>
  "A "
  <em>simple</em>
  " example"
</p>

Attribute Operator: “[ ]”

Specifies attributes other than class and id (comma-separated if more than one)

a#myId.myClass[href=http://foo.com,data-type=permalink] <a
  href="foo.com"
  data-type="permalink"
  id="myId"
  class="myClass"
/>

Advanced Usage: Templating & Data Binding

To be completed...

  1. bind
  2. addTemplate
  3. getTemplate
  4. addConditionalsMap