Mustache.js

Jan writes:

Today, I’m showing you something that is not directly related to CouchDB or Couchio, but it is sure useful when writing web applications: mustache.js.

{{ mustache }}

Mustache is a template engine available in many languages (Ruby, JavaScript, Python, Erlang, node.js, PHP, Perl, Go, Lua and many more). A template engine? “Are you kidding me, why is this relevant, go and bore someone else!”, you might say, but you’re staying because you’re intrigued by the mustache; don’t be afraid, everybody is.

Logic-less Templates

The story goes like this: There is a need for templating because mixing code and HTML is a bad idea (looking at you PHP); so we invent a templating language. Since we need to be able to do some logic in the template (loop, conditionally show or don’t show something, call helper functions etc.), we make our template language turing complete (looking at you Smarty) and then we have code in templates again, which sucks; on top of that, we have another language we need to learn to write, debug and teach.

Mustache does away with code in templates while remaining useful. Its concepts are by no means new or revolutionary, but the careful selection of features and design is what makes it so interesting (and successful!).

Mustache takes separation of concerns seriously. You can write as much logic and code as you like, call helpers and whatnot, all in your favourite, turing complete programming language, just not in your templates. It introduces a second part to a template, the view. The view in mustache is just an object with attributes and methods that correspond to your placeholder names in your template. Here’s an example in JavaScript:

view.js:

{
  name: "Chris"
}

template.html:

Hello {{name}}!

Mustache result:

Hello Chris!

Easy, no? — Next you want to write some code that runs before your data goes into the template? No problem:

{
  name: "Chris",
  birthtimestamp: "405674640",
  birthday: function() {
    var birthday = new Date(this.birthtimestamp * 1000) // Date() likes ms
    var day = birthday.getDate();
    var month = birthday.getMonth() + 1; // some moron thought it was a
                                         // good idea to return 0-11 here
    var year = birthday.getFullYear();
    return day + "-" + month + "-" + year;
  }
}

template.html:

Hi {{name}}!
Your Birthday is {{birthday}}.

Mustache result:

Hi Chris!
Your Birthday is 9-11-1982

Easy peasy!

Sections

On websites we often display rows of things, lists of todo items, shopping cart contents, blog posts you name it. In Mustache, a section is just a block of HTML that is rendered zero or more times.

First, zero times:

view.js:

{
  list: []
}

template.html:

Eddie’s list:
{{#list}}
  {{item}}
{{/list}}

Mustache result:

Eddie’s list:

The block is empty because the array in the view is empty. Mustache goes one step further and doesn’t just look for empty arrays but any falsy JavaScript value (false, 0, “”, [], null, undefined). This is neat, because it behaves like a boolean-conditional block.

Now lets loop for real!

view.js:

{
  list: [
    {item: "Chair"},
    {item: "Table"},
    {item: "Tree"}
  ]
}

template.html:

Eddie’s list:
{{#list}}
  {{item}}
{{/list}}

Mustache result:

Eddie’s list:
  Chair
  Table
  Tree

Partials

Mustache.js has a few more features that you can read all about in the README, but there’s one more I’d like to share with you: partials.

Initially, I was scared of partials. In every template language I used before partials were some scary complex thing that I barely understood and had trouble using (yeah, I’m not very smart). Partials are good for including often-used snippets, like navigation or headers and footer.

In mustache, partials are dead simple. You have a special tag {{>partial}} that you put where you want to insert the partial, create the partial that you want to be displayed and that’s it. It is just a basic replace or macro include mechanism. Nothing fancy. Here’s how it looks like:

view.js:

{
  name: "Chris",
  title: "Welcome to Eddie’s site."
}

template.html:

{{>header}}
Hi {{name}}!

header.html:

<title>{{title}}</title>

Mustache result:

<title>Welcome to Eddie’s site.</title>
Hi Chris!

Easy again; no magic.

Simplicity Wins

The big appeal for mustache is its no frills simplicity. There’s no funky magic, no bad hidden surprises and of course the mustache culture :)

On top of that, the different language implementations strive to be compatible in the way they interpret templates. So you should be able to use the same templates in say Rails in the backend and in the Browser.

Mustache.js e.g. is in use today on twitter.com, used by millions of people daily. If it would include every feature in the world and be thousands of lines of code, the Twitter engineers would never have picked it; instead it is small, lean and concise.

Go mustache! — I hope you enjoy mustache.js as much as I and many other people do. My first use-case for it was in CouchApps of course and it works great there, but it works just fine with any other web technology :)

Summing up: Read all about it or try a demo.