Easy HTML Templates With Mustache
Easy HTML Templates With Mustache
1
Along the way, you’ll see plenty of code examples
that show you how Mustache works. At the end of
the tutorial, there’s a complete example that uses
Mustache, along with jQuery, to create a simple
Ajax-based product list page.
What is Mustache?
Mustache is a simple template system that you can
use when building websites and web apps. By
using a template system, you can keep your back-
end code separate from the markup that displays
the front end to the user. This clean separation
gives you many advantages. For example, it makes
it easy for a designer to work on a website’s visual
design without the risk of messing up the site’s
code. It also makes it easy for you to change the
design at a later point without impacting the back-
end code.
2
One of Mustache’s big plus points is that is logic-
less, which means it keeps your templates very
neat and tidy. There are no messy if ... then or
looping constructs embedded within a Mustache
template; it’s all just markup and simple Mustache
tags. All the logic is hidden away inside your data
objects (and the code that creates or fetches them).
3
Mustache is used by a lot of popular websites and
web apps, including Twitter and OMGPOP (maker
of the ever-popular Draw Something game). Here’s
a list of sites that use Mustache.js, the JavaScript
version of Mustache.
<ul>
<li>Product: {{name}}</li>
<li>Colour: {{colour}}</li>
<li>Price: ${{price}}</li>
</ul>
4
As you might have guessed, the {{ and }} delimiters
are where Mustache gets its name from!
5
JavaScript (or JSON) object. But essentially you
pass Mustache a list of name/value pairs.
<ul>
<li>Product: SuperWidget</li>
<li>Colour: Green</li>
<li>Price: $19.99</li>
</ul>
Installing Mustache
The Mustache processor is available in a wide
range of languages. As a general rule, you install
Mustache like this:
6
Click the ZIP button to download the repository Zip
file.
Unzip the downloaded file, and move the resulting
folder to your website.
Include the relevant library file (such as
mustache.js or Mustache.php) in your web pages
or server-side scripts.
There are some subtle differences between the
Mustache implementations for different languages.
Make sure you read the documentation specific to
the Mustache processor you’re using.
7
Here are some examples:
JavaScript:
output = Mustache.render( template, data );
PHP:
$m = new Mustache;
$output = $m->render( $template, $data );
Perl:
use Template::Mustache;
$output = Template::Mustache->render( $template,
$data );
8
we can run the demo straight in the browser,
without needing to write any server-side code.
Grab mustache.js
To start building the demo page, you first need to
install the JavaScript Mustache processor:
9
The HTML page
Here’s the demo page — save it as demo.html in
the same folder as your mustache.js file:
<!doctype html>
<html>
<head>
<title>A Simple Mustache Demo</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css" />
<script type="text/javascript"
src="http://code.jquery.com/jquery-
1.7.1.min.js"></script>
<script type="text/javascript"
src="mustache.js"></script>
<script type="text/javascript" src="mustache-
demos.js"></script>
</head>
<body>
<div id="wrap">
<div class="template">
<h3>Mustache Template:</h3>
<textarea id="template">
10
<h4>Product Info: {{name}}</h4>
<ul>
<li>Product: {{name}}</li>
<li>Colour: {{colour}}</li>
<li>Price: ${{price}}</li>
</ul>
</textarea>
</div>
<div class="data">
<h3>Data Object:</h3>
<textarea id="data">
var data = {
"name": "SuperWidget",
"colour": "Green",
"price": "19.99"
}
</textarea>
</div>
<div class="process"><button
onclick="process()">Process Template</button></div>
<div class="html">
<h3>HTML Result:</h3>
11
<textarea id="html">
</textarea>
</div>
<div class="result">
<h3>How It Looks:</h3>
<div id="result">
</div>
</div>
</div>
</body>
</html>
A style.css include
This contains the CSS to display the demo page.
We’ll create this file shortly.
Three JavaScript includes
12
We’ve included jQuery, the mustache.js library
file, and a mustache-demos.js JavaScript file
(which we’ll create in a moment).
A textarea with an id of "template"
This contains the Mustache template that we
want to use. Notice that the template is mainly
HTML markup, with a few Mustache tags,
indicated by the {{ and }} delimiters.
A textarea with an id of "data"
This contains JavaScript code that creates an
object variable called data, with three properties:
"name", with a value of "SuperWidget"; "colour",
with a value of "Green"; and "price", with a value
of "19.99".
A button with an id of "process"
When clicked, this button calls a JavaScript
function, process(), which runs the Mustache
processor to produce the finished HTML. We’ll
create this function in a moment.
A textarea with an id of "html"
13
This will contain the finished HTML generated
by the Mustache processor, displayed as source
markup.
A div with an id of "result"
This will contain the finished HTML generated
by the Mustache processor and rendered by the
browser, so that you can see how the ends
result looks in the page.
The style sheet
Here’s the style sheet for the page — save it as
style.css in the same folder as demo.html:
body {
font-family: "Georgia", serif;
line-height: 1.8em;
color: #333;
}
#wrap {
width: 57em;
}
14
padding: 1em;
}
textarea {
font-family: Courier, fixed;
}
.result div {
border: 1px solid #333;
}
h3 {
display block;
margin: 2em 0 0 1.5em;
}
.process {
display: block;
clear: both;
margin: 1em 0;
width: 56em;
text-align: center;
}
button {
font-size: 1.5em; margin-top: 1em;
}
15
This CSS aligns the various elements in the demo
page — including the textareas, the #result div, and
the #process button — and styles them.
The JavaScript
Finally, here’s the JavaScript code for the demo
page — save it as mustache-demos.js in the same
folder as demo.html:
function process() {
var template, data, html;
template = $('#template').val();
eval( $('#data').val() );
html = Mustache.render( template, data );
$('#html').text( html );
$('#result').html( html );
}
16
1. Extracts the template code stored in the
#template textarea, and stores it in the variable
template.
2. Calls eval() on the contents of the #data
textarea, which creates the data object.
3. Calls Mustache.render(), passing in the
Mustache template stored in template, as well
as the data object stored in data. This generates
the finished markup, which the code then stores
in the html variable.
4. Inserts the markup stored in html into the #html
textarea, as well as the #result div, so that the
markup can be both viewed by the user and
rendered by the browser.
Try it out!
To try out the demo, open demo.html in your
browser, or press the button below:
View Demo »
You’ll see four boxes in the page. The Mustache
Template box and the Data Object box are filled
17
with the template code and the JavaScript code to
generate the data object. The HTML Result and
How It Looks boxes are initially blank.
18
The demo page in action. The code in the Mustache
Template and Data Object boxes combine to
produce the code in the HTML Result box. The How
It Looks box shows how the HTML renders.
Try editing the contents of the Mustache Template
and Data Object boxes, then pressing the Process
Template button again to see the results. This is a
great way to play with Mustache and see what it can
do.
19
missing variables; and how Mustache HTML-
escapes certain characters within variable values.
…or:
"price": calcPrice
20
Accessing object properties and methods
Your data object can also contain other objects —
for example:
{
"name": "SuperWidget",
"colour": "Green",
"price": {
"regular": "19.99",
"discount": "14.99"
}
}
<ul>
<li>Product: {{name}}</li>
<li>Colour: {{colour}}</li>
<li>Regular Price: ${{price.regular}}</li>
<li>Discount Price: ${{price.discount}}</li>
</ul>
21
Combining the above object and template produces
the following output:
<ul>
<li>Product: SuperWidget</li>
<li>Colour: Green</li>
<li>Regular Price: $19.99</li>
<li>Discount Price: $14.99</li>
</ul>
Missing variables
If you use a variable name in your template that
doesn’t appear in the corresponding data object,
Mustache simply replaces the tag with an empty
string. For example, this Mustache template:
22
produces this result:
Hello, John !
HTML escaping
Mustache automatically replaces certain HTML
characters, such as < and >, with their equivalent
HTML entities, such as < and >. If you don’t
want Mustache to HTML-escape a value, put triple
braces around the variable name instead of double
braces, like this:
{{{name}}}
A quick demo
23
Press the button below to see expressions,
functions, accessing object properties, missing
variables, and HTML escaping in action:
View Demo »
Working with sections
24
{{#sectionName}}
(more markup in here)
{{/sectionName}}
Conditional sections
A conditional section is a block of markup that is
displayed only if a certain condition is true. Here’s
an example.
{{#inStock}}
<li><a href="#">Buy Now!</a></li>
{{/inStock}}
25
On the other hand, if your data object looks like
this:
{
"inStock": false
}
Or like this:
{
}
Inverted sections
Inverted sections are the opposite of conditional
sections. With an inverted section, the section’s
content is only output if the section’s variable is
false.
26
{{^inStock}}
<li>Sorry, out of stock.</li>
{{/inStock}}
"inStock": false
Repeating sections
27
Repeating sections are handy when you want to
display a list or table of related data in the page.
You create a repeating section like this:
28
<ul>
{{#product}}
<li>{{name}}: ${{price}}</li>
{{/product}}
</ul>
{
"product": [
{
"name": "SuperWidget",
"price": "19.99"
},
{
"name": "WonderWidget",
"price": "24.99"
},
{
"name": "MegaWidget",
"price": "29.99"
}
]
}
29
And finally, the resulting output:
<ul>
<li>SuperWidget: $19.99</li>
<li>WonderWidget: $24.99</li>
<li>MegaWidget: $29.99</li>
</ul>
30
Partials allow you to include one Mustache
template inside another. This lets you keep your
templates modular and organized.
var partials = {
myPartial: "templateString",
anotherPartial: "templateString"
...
};
{{>partialName}}
{{>myPartial}}
31
You can also include a partial within another
partial, which lets you make nested includes.
var partials = {
productInfo: "
<ul>
<li>Name: {{name}}</li>
<li>Colour: {{colour}}</li>
<li>Price: ${{price}}</li>
{{>buyLink}}
</ul>
",
32
buyLink: "
{{#inStock}}
<li><a href='#'>Buy Now!</a></li>
{{/inStock}}
{{^inStock}}
<li>Sorry, out of stock.</li>
{{/inStock}}
"
};
33
Here’s the data object that we’ll use for our
product data:
var data = {
"name": "SuperWidget",
"colour": "Green",
"price": "19.99",
"inStock": true
}
<h3>Product: SuperWidget</h3>
<ul>
<li>Name: SuperWidget</li>
<li>Colour: Green</li>
<li>Price: $19.99</li>
<li><a href='#'>Buy Now!</a></li>
</ul>
34
Bringing it all together
35
mustache.js and style.css files that you used
earlier in the tutorial into the same folder.
<!doctype html>
<html>
<head>
<title>Complete Mustache Demo: Product List</title>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css" />
<script type="text/javascript"
src="http://code.jquery.com/jquery-
1.7.1.min.js"></script>
<script type="text/javascript"
src="mustache.js"></script>
<script type="text/javascript">
function getProducts() {
36
$.getJSON( "products.txt", null, function( ajaxData
) {
data = ajaxData;
gotData = true;
if ( gotTemplate ) processTemplate();
} );
}
function processTemplate() {
html = Mustache.render( template, data );
$('#productList').html( html );
}
</script>
<style>
</style>
</head>
<body>
37
<button onclick="getProducts()">Get
Products</button>
<div id="productList"> </div>
</body>
</html>
A heading
A Get Products button that, when pressed,
calls the JavaScript function getProducts(), and
An empty #productList div that will contain the
products table.
The page also contains the JavaScript to fetch and
display the product list. First the JavaScript sets
up some variables:
38
gotTemplate and gotData will be used to track
when the JavaScript has finished fetching the
Mustache template and the product data
respectively. When both have been fetched,
the list can be displayed.
The getProducts() function runs when the user
presses the Get Products button. It makes two
calls to jQuery Ajax methods in order to retrieve
two files from the server:
productListTemplate.mustache
The function fetches this file using the jQuery
get() method. This is the Mustache template file
for the products list; we’ll create this file in a
moment.
products.txt
This file is fetched using the jQuery getJSON()
method. This method works like get(), but is
specifically designed for retrieving JSON data,
which it then parses and turns into a JavaScript
object. products.txt contains the product data in
39
JSON format. Again, we’ll create this in a
minute.
With both Ajax requests, the code passes in an
anonymous callback function that runs once the
request completes. Each function does the
following:
40
stores the markup in the html variable, which it
then passes to jQuery’s html() method to insert the
markup into the #productList div, displaying the
table to the user.
<table>
<tr>
<th>Product</th>
<th>Colour</th>
<th>Price</th>
<th>Buy</th>
</tr>
{{#product}}
<tr>
<td>{{name}}</td>
<td>{{colour}}</td>
<td>${{price}}</td>
41
{{#inStock}}<td><a
href="buy.php?productId={{id}}">Buy
Now!</a></td>{{/inStock}}
{{^inStock}}<td>Out of Stock</td>{{/inStock}}
</tr>
{{/product}}
</table>
42
2. Two conditional sections. The markup between
{{#inStock}} ... {{/inStock}} is displayed if the
inStock variable is true; it comprises a dummy
“Buy Now!” link that uses the id variable to
identify the product. The markup between
{{^inStock}} ... {{/inStock}} is displayed if inStock
is false; it simply displays an “Out of Stock”
message.
The data file
The last file we need to create contains the
product data in JSON format. Save the following
code as products.txt in the same folder as
productList.html:
{
"product": [
{
"id": 1,
"name": "SuperWidget",
"colour": "Green",
"price": "19.99",
"inStock": true
},
{
"id": 2,
43
"name": "WonderWidget",
"colour": "White",
"price": "24.99",
"inStock": true
},
{
"id": 3,
"name": "MegaWidget",
"colour": "Purple",
"price": "29.99",
"inStock": false
},
{
"id": 4,
"name": "HyperWidget",
"colour": "Yellow",
"price": "49.99",
"inStock": true
}
]
}
44
In a real-world site or app, this file would likely be
dynamically generated by a server-side script that
pulls the data from a database, rather than stored
as a static file on the server.
Try it out!
To try out the product list demo, browse to the
URL for the productList.html file in your website —
for example, http://mywebsite/productList.html —
or press the button below to see it running on our
server:
45
the files have been fetched, processTemplate()
calls Mustache’s render() method to combine the
Mustache template with the product data and
produce the product list table, which is then
displayed in the page:
46
What Mustache is, and why it’s useful.
A basic example of a Mustache template with
tags and variables, as well as a data object.
How to install the Mustache processor on your
website.
Running the processor by calling the render()
method.
Building a simple demo page that you can use
to try out various Mustache features.
Using expressions and functions in data
objects.
How to access object properties and methods
in your Mustache templates.
What happens when Mustache can’t find a
variable.
How Mustache escapes HTML characters, and
how to bypass escaping.
The concept of Mustache sections, including
conditional sections, inverted sections, and
repeating sections (loops).
How to add comments in Mustache templates.
47
Including one Mustache template inside
another by using partials.
A complete example that uses JavaScript,
jQuery, Ajax and Mustache to build a simple
product list page.
There are a few more Mustache features worth
checking out, including lambdas (which let you
manipulate un-parsed sections of Mustache
templates) and the ability to change the default
Mustache delimiters, {{ and }}, to something else.
To find out more, take a look at the Mustache
spec.
48