Sunteți pe pagina 1din 48

Easy HTML Templates with Mustache

Templates are a great way to separate your


website’s code from its design. There are many
great web template systems available for different
languages and platforms, including Smarty for PHP
and the Django template language for Python.

In this tutorial you’ll explore Mustache, a relatively


new and very simple template system that you can
easily use to create HTML templates. You’ll look at
various topics, including:

 The advantages of using Mustache


 How to install and use the Mustache processor
 How Mustache tags, variables, and data objects
work
 Using sections to create conditions and loops
 Including one Mustache template inside another
 …and lots more!

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).

Another advantage of Mustache is that you’re not


tied to any particular language. Mustache
processors are available in many languages,
including JavaScript, PHP, Perl, Ruby, Python,
Java and lots more.

You can use Mustache for practically any kind of


template, including config files and even source
code. However, this article concentrates on using
Mustache to build HTML templates, which is a very
popular use of the system.

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.

A basic Mustache example


What does a Mustache template look like? Here’s a
simple example:
<h4>Product Info: {{name}}</h4>

<ul>
<li>Product: {{name}}</li>
<li>Colour: {{colour}}</li>
<li>Price: ${{price}}</li>
</ul>

As you can see, this template is essentially HTML


mixed with a few special Mustache tags. A
Mustache tag begins with two opening braces ({{)
and ends with two closing braces (}}).

4
As you might have guessed, the {{ and }} delimiters
are where Mustache gets its name from!

Inside each tag is the name of a variable (in this


case, name, colour, and price). When Mustache
processes the template, it replaces each variable
name with an actual value.

But where does Mustache get the values for the


variables in the template? The answer is that, when
you pass the template to the Mustache processor,
you also pass an object or hash containing the
variable names and their associated values:
{
"name": "SuperWidget",
"colour": "Green",
"price": "19.99"
}

The exact format of the object or hash depends on


the language you’re using. The above example is a

5
JavaScript (or JSON) object. But essentially you
pass Mustache a list of name/value pairs.

When you pass the template and object to the


Mustache processor, it combines the two and
returns the final HTML, with the variable names
replaced by their values:
<h4>Product Info: SuperWidget</h4>

<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:

Visit the GitHub page for your chosen language


(for example, JavaScript or PHP).

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.

Running the Mustache processor


The syntax for calling the Mustache processor
depends on the language you are using.
Essentially though, you call the Mustache class’s
or object’s render() method, passing in the
template string followed by the data object. The
processor then combines the template with the
data object to produce the final markup string,
which it returns.

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 );

A Mustache demo page


Let’s get going with a simple demo page that shows
Mustache in action. We’ll use mustache.js — the
JavaScript implementation of Mustache — so that

8
we can run the demo straight in the browser,
without needing to write any server-side code.

The JavaScript version of Mustache is very handy


for Ajax-driven web apps. Your app can pull JSON
data from the server using Ajax, then combine the
data with a Mustache template to create the final
markup for displaying in the page. You’ll learn how
to do this in the complete example at the end of the
tutorial.

Grab mustache.js
To start building the demo page, you first need to
install the JavaScript Mustache processor:

1. Create a folder somewhere on your computer


2. Download and unzip the JavaScript Mustache
processor
3. Copy the resulting mustache.js file into your
folder

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>

<h1>A Simple Mustache Demo</h1>

<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>

This page contains the following elements:

 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;
}

textarea, .result div {


font-size: .8em;
width: 29em;
height: 15em;
margin: 1em 2em 2em 2em;

14
padding: 1em;
}

textarea {
font-family: Courier, fixed;
}

.template, .html, .data, .result {


float: left;
}

.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 );
}

This function, process(), runs when the user


presses the Process Template button in the page.
The function:

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.

Now press the Process Template button. This runs


the Mustache processor, passing in the template
and the data object. The resulting markup then
appears in the HTML Result box, and is rendered
in the How It Looks box:

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.

Delving deeper into variables


So far you’ve learned how to create a Mustache
variable by placing the variable name inside a
Mustache tag, then creating a property with the
same name inside your data object.

Let’s look at some more features of Mustache


variables. In this section you’ll explore expressions
and functions; how to access object properties and
methods within templates; how Mustache handles

19
missing variables; and how Mustache HTML-
escapes certain characters within variable values.

Expressions and functions


With most languages, you’re not limited to using
literal values in your Mustache data objects. You
can also use expressions and functions as values.
This means your object can contain properties such
as:
"price": parseFloat(netPrice+tax).toFixed(2)

…or:
"price": calcPrice

(where calcPrice() is a function). Mustache then


replaces the variable tag with the result of the
expression, or the return value of the function, in
the output.

One notable exception to this rule is JSON, which


doesn’t allow expressions as property values.

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"
}
}

To access a property or method of an object from


within your Mustache template, you can use the dot
(.) notation, like this:
<h4>Product Info: {{name}}</h4>

<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:

<h4>Product Info: SuperWidget</h4>

<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:

Hello, {{first}} {{last}}!

when combined with this data object:


{
"first": "John",
}

22
produces this result:

Hello, John !

HTML escaping
Mustache automatically replaces certain HTML
characters, such as < and >, with their equivalent
HTML entities, such as &lt; and &gt;. 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}}}

Alternatively, you can place an ampersand after


the opening double brace, 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

Sections let you add more power to your templates.


Using sections, you can display a chunk of markup
only if a certain condition is true (or false). You can
also create repeating sections, which let you
display lists and tables of data.

The basic syntax for a section looks like this:

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.

Say your template looks like this:

{{#inStock}}
<li><a href="#">Buy Now!</a></li>
{{/inStock}}

If your data object looks like this:


{
"inStock": true
}

…then the output will look like this:

<li><a href="#">Buy Now!</a></li>

25
On the other hand, if your data object looks like
this:

{
"inStock": false
}

Or like this:
{
}

…then nothing will be output.

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.

You create an inverted section by replacing the "#"


character with a "^" character. For example:

26
{{^inStock}}
<li>Sorry, out of stock.</li>
{{/inStock}}

The li element in the above example is only output


if the value of the inStock variable is false.

To try out conditional sections and inverted


sections, press the button below:

Press the Process Template button. Since the


value of inStock is true, the “Buy Now!” link is
displayed. Now try changing inStock to false in the
data object:

"inStock": false

Now when you press the Process Template


button, the “Sorry, out of stock” message is
displayed instead.

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:

1. Add a section ( for example, {{#mySection}} ...


{{/mySection}} ) to your Mustache template.
2. Inside the section, place the markup and any
variable tags that you want to display for each
item in the list.
3. Add a list (or array) property to your data object.
Give the property the same name as the section
(for example, mySection).
4. Each item in the list should be an object
containing the properties corresponding to the
variable tags you added in Step 2.
The Mustache processor then loops through the
objects in the list. For each object, it replaces the
variable tags in the section with the properties of
the object, and outputs the section’s markup.

Here’s an example. First, the Mustache template:

28
<ul>
{{#product}}
<li>{{name}}: ${{price}}</li>
{{/product}}
</ul>

Next, the data object:

{
"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>

You can try out this example by pressing the


button below:

Adding comments in Mustache


To insert a comment in a Mustache template, use
the following syntax:

{{! this is a comment }}

The whole comment tag is ignored by the


Mustache processor.

Including Mustache templates with partials

30
Partials allow you to include one Mustache
template inside another. This lets you keep your
templates modular and organized.

In the JavaScript version of Mustache, you create


an object containing all your partials:

var partials = {
myPartial: "templateString",
anotherPartial: "templateString"
...
};

Then, to insert a partial at a given point in a


template, you use the syntax:

{{>partialName}}

So to include the partial called "myPartial", you’d


write:

{{>myPartial}}

31
You can also include a partial within another
partial, which lets you make nested includes.

Then, when you run the Mustache processor, you


pass your partials object as the third argument,
like this:

html = Mustache.render( template, data, partials );

Here’s an example of partials in action. First, we’ll


create a couple of partials, productInfo and
buyLink:

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}}
"
};

productInfo displays a product’s name, colour and


price, It also includes the buyLink partial, which
displays the “Buy Now!” link (or the “Sorry, out of
stock” message if the product is out of stock).

Now let’s create our template:

var template = "<h3>Product: {{name}}</h3>


{{>productInfo}}";

This template displays the product name inside an


h3 element, then includes the productInfo partial to
display the product info.

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
}

Finally, we call the Mustache render() method to


create the final markup:

html = Mustache.render( template, data, partials );


alert( html );

This displays the following alert box:

<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

Let’s build a complete JavaScript demo that shows


off some of Mustache’s great features. We’ll
create a simple product list page with a Get
Products button. When the user clicks the button,
the JavaScript code uses Ajax to fetch the product
data from the server, then uses a Mustache
template to display the product data in an HTML
table.

The HTML page


First, create the main page for the product list
demo. Save the following code as productList.html
in a folder in your website. Also, copy the

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">

var template, data, html;


var gotTemplate, gotData;

function getProducts() {

gotTemplate = gotData = false;

$.get( "productListTemplate.mustache", null,


function( ajaxData ) {
template = ajaxData;
gotTemplate = true;
if ( gotData ) processTemplate();
} );

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>

table { width: 100%; border-spacing: 1px; border:


none; }
th { text-align: left; background-color: #EFEFD7;
color: #000000; font-weight: bold; padding: 4px; }
td { text-align: left; background-color: #F7F7E6;
color: #000000; font-weight: normal; padding: 4px; }
button { margin-bottom: 20px; }

</style>

</head>
<body>

<h1>Complete Mustache Demo: Product List</h1>

37
<button onclick="getProducts()">Get
Products</button>
<div id="productList"> </div>

</body>
</html>

The page’s body contains:

 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:

 template, data and html will hold the Mustache


template, the data object, and the final product
list HTML respectively.

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:

1. It stores the returned data in the appropriate


variable (template or data).
2. It set the appropriate tracking variable to true
(gotTemplate or gotData).
3. If both tracking variables have been set to true,
it calls processTemplate() to display the product
list.
If you’re new to Ajax programming or jQuery,
check out Ajax with jQuery: A Beginner’s Guide.

Finally, the processTemplate() function calls


Mustache.render() to create the product list
markup, passing in the Mustache template stored
in template, and the data object stored in data. It

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.

The Mustache template


Here’s the Mustache template that displays the
product list table — save it as
productListTemplate.mustache in the same folder
as productList.html:

<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>

As you can see, the template is HTML markup


interspersed with Mustache tags. The template
comprises:

 A header row containing the column headers:


Product, Colour, Price and Buy.
 A {{#product}} ... {{/product}} Mustache section.
This section displays a row of product data in
the table. Since the product property in our
data object is an array of objects (as you’ll see
in a moment), this section will run repeatedly to
display all the rows in the products table.The
section contains:
1. Mustache variables to display the product
name, colour, and price.

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
}
]
}

This file defines a JSON object that contains a


product array. The product array contains four
elements, each of which is an object representing
a product. Each product object contains id, name,
colour, price and inStock properties.

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:

Since the demo uses Ajax to fetch the template


and data files, you need to view the demo running
on a web server. Opening the productList.html file
directly in your browser probably won’t work.

Now press the Get Products button in the page.


When you do this, the getProducts() function runs,
retrieving the productListTemplate.mustache and
products.txt files from the server via Ajax. Once

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:

The product list demo. When you click Get


Products, the JavaScript in the page fetches the
Mustache template and data via Ajax, then
combines them to display the table.
Summary
In this article you’ve explored the Mustache
template system, and seen how you can easily
use it to build clean, logic-less templates. You’ve
looked at:

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

S-ar putea să vă placă și