Creating HTML Templates with Mustache.js

Tweet

Web applications use MVC architectures to separate business logic from the presentation views. Complex projects which involves large amounts of client side HTML manipulation with JavaScript can be difficult to maintain. In such scenarios we can use template systems to increase reusability and ease the task of managing views. Mustache.js provides a well documented template system which can be used to manage your templates. And, since mustache supports various languages, we don’t need a separate templating system on the server side. This article covers the basics of working with mustache.

Why We Need Template Systems

Most developers that are not aware of template systems create new chunks of HTML code and dynamically insert them into the DOM using JavaScript. A common way of doing this is to specify the HTML elements in a string and then set the innerHTML property or call the jQuery html() method. An example of this technique is shown below.

var dynamic_html = "<div><span>Highlighted</span><span>Author</span></div>";

document.getElementByID("container").innerHTML = dynamic_html;

Another method for building the DOM is to create elements and append them individually, as shown below.

var title = document.createElement('div');
var highlight = document.createElement('span');
var highlight_text = document.createTextNode("Highlight");
var author = document.createElement('span');
var author_text = document.createTextNode("Author");
var container = document.getElementById('container');

highlight.appendChild(highlight_text);
title.appendChild(highlight);
author.appendChild(author_text);
title.appendChild(author);
container.appendChild(title);

Both the methods above can be used effectively to add elements dynamically into your document. Consider a situation where we have a very well designed bullet list which needs to be used across three different types of pages in our site. Using these techniques, we would have to repeat the HTML code the list in three different locations. This is generally considered to be bad coding practice.

In such scenarios we can use predefined templates in different locations without repeating the code. Mustache.js is a very popular template engine using JavaScript. Since mustache provides both server side and client side templates for numerous languages, we don’t have to worry about choosing separate template engines.

Getting Started with Mustache.js

Mustache is an open source logic-less template system developed for languages such as JavaScript, Ruby, Python, PHP, and Java. You can grab a copy of the library by visiting the official page on GitHub. Mustache provides templates and views as the basis for creating dynamic templates. Views contain the data to be included in the templates as JSON. Templates contain the presentation HTML or data with the template tags for including view data. Earlier, we mentioned mustache as logic-less. This means the templates will not contain any if-else conditions or for loops. Now, let’s get started on mustache templates using a simple example.

<!doctype html>
<html lang="en">
  <head>
    <title>Mustache.js Inline Method</title>
    <script type="text/javascript" src="mustache.js" ></script>
    <script>
      var view = {
        name : "Joe",
        occupation : "Web Developer"
      };

      function loadtemp(){
        var output = Mustache.render("{{name}} is a  {{occupation}}", view);
        document.getElementById('person').innerHTML = output;
      }
    </script>
  </head>
  <body onload="loadtemp()" >
    <p id="person"></p>
  </body>
</html>

First, we need to include the mustache.js file in the document. Then we can work on creating mustache templates. In the above example we have a view containing the name and occupation of a person. Then, we have the template inside the render() function with presentation code and tags for name and occupation data. Tags are indicated by the double braces, or mustaches, that surround them. Now, let’s take a look at how the render() method works.

Rendering Mustache Templates

The following code shows the implementation of the render() function inside the mustache.js file. Three parameters can be passed to render(). The first two parameters, template and view are mandatory. partials can be considered as dynamic templates which you can inject into your main template. In our previous example, we passed the template as an inline parameter and the view as the second parameter, and assigned the result to the output variable.

Writer.prototype.render = function (template, view, partials) {
  return this.compile(template)(view, partials);
};

This is the most basic form of templating with mustache. Let’s see the other methods available for creating more organized code.

Defining Mustache Templates

There are various methods for defining mustache templates in your application. These methods are similar to including CSS using inline styles, inline stylesheets, and external stylesheets. The example we discussed earlier can be considered as an inline method since we are passing the template directly to the function. This method prevents the possibility of reusable templates. Let’s see how we can define templates as inline script templates as opposed to directly passing to the function.

Templates as Inline Scripts

We can define template data inside of a <script> tag and include it in the HTML document. To prevent the browser from executing the template code, we must change the MIME type to something other than text/javascript. Some common MIME types are text/html , text/template, and text/mustache. The following example is a simple template using this method.

<script id="sample_template" type="text/html">
<h1>{{name}}</h1>
</script>

You can include as many templates in a document as you wish with different IDs. When you want to use the template, get the HTML inside the script tag using innerHTML, and pass it as a template. Our first example will change to the following code.

<script type='text/javascript'>
  var template = document.getElementById('sample_template').innerHTML;
  var output = Mustache.render(template, view);
  document.getElementById('person').innerHTML = output;
</script>

As you can see, templates are stored separately and used dynamically when required. This method increases the possibility of reusing templates. However, using inline scripts limits the templates’ scope to a single page. If you have multiple pages, you have to define your templates again. So, including templates in an external file will be the ideal solution – just like with CSS.

Templates as External HTML Snippets

In this technique we are going to use jQuery to implement templating. jQuery provides a function called load(), which can be used to fetch part of an external document. We are going to use this method to load templates dynamically from our external templates files. The load() function executes scripts instead of returning them, so we cannot create templates inside of script tags as we did in the previous method. The following example shows the external template files we are going to use.

<div id="template1" >
<h1>{{name}}</h1>
</div>

<div id="template2" >
<div>{{name}}</div>
</div>

<div id="template3" >
<p><span>{{name}}</span></p>
</div>

We have used <div> elements for templates instead of scripts to keep it compatible with jQuery’s load() function. Here, we have three different templates with three different IDs. Now, let’s move on to using these templates in your pages.

<!doctype html>
<html lang="en">
  <head>
    <title>Mustache.js External Method</title>
    <script type="text/javascript" src="jquery.js" ></script>
    <script type="text/javascript" src="mustache.js" ></script>
    <script>
      $(document).ready(function(){
        var view = {
          name : "Joe",
          occupation : "Web Developer"
        };

        $("#templates").load("template.html #template1",function(){
          var template = document.getElementById('template1').innerHTML;
          var output = Mustache.render(template, view);
          $("#person").html(output);
        });
      });
    </script>
  </head>
  <body>
    <p id="person"></p>
    <div id="templates" style="display: none;"></div>
  </body>
</html>

jQuery inserts the returned document into an HTML element instead of assigning it to a variable. So, we need a dummy container to keep the templates. I have used the templates container which is hidden by default. The example above retrieves template1, and loads it. Then, we can get the template from the dummy container and pass it to mustache for rendering. This is how the external method works. We can also get the data from a server using an AJAX request.

Conclusion

Template engines and frameworks are important in managing complex systems with dynamically changing presentation views. Mustache.js is one of the best choices for managing templates on the client side. We started this tutorial by explaining why templates are important. Then, we moved onto various techniques of using mustache templates. Now you will be able to choose the method of implementing mustache templates in your projects.

We have completed exploring various techniques for using mustache templates, but mustache also comes with tags such as variables, sections, functions and partials, which are used to manage complex templates. Discussing the syntax of each tag is beyond the scope of this tutorial. You can find a comprehensive guide to mustache tags on the mustache GitHub page.

Feel free to share your previous experiences in working with mustache.js!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Mohammad Ali

    Nicely put, just what I needed to kick start using mustache. Thanks for a very comprehensive article!

    • Rakhitha Nimesh

      Thanks for your interest in my article. Feel free to share your experiences once you get familier with mustache

  • http://www.audero.it/ Aurelio De Rosa

    Very good article, thank you. I’ll use it in my next projects if I’ll need.

    • http://www.innovativephp.com Rakhitha Nimesh

      Hello Aurelio

      Thank you very much.

      I am glad that experienced developer and author like you found my article to be useful.

  • Matt Stevens

    how would you call these template1-3.html files from CouchDB?

    • http://www.innovativephp.com Rakhitha Nimesh

      Hi Matt

      I haven’t worked with CouchDB. As far as I know CouchDB is a NoSql database. So how is that going to relate with template files?

      Can you please explain further.