Logic-less templates with Mustache

Sunday December 11, 2011 at 14:03 | tutorial

Mustache

As the frontpage of the Mustache project already states: “logic-less templates.” The description couldn't be more to the point. As stated in my previous blog, it's important to separate logic from presentation. It allows for more maintainable code and makes debugging easier.

This applies to most web-applications of today that use a server-side language to handle data and use HTML to present the data. To create this separation cleanly with clear exclusion of logic from the HTML template, the influence of an external script or library is almost always needed. Mustache does exactly that.

Mustache vs. other templating libraries

Why specifically Mustache? There are quite a number of libraries that help with the separation of logic from templates for any language. In my opinion, almost none of those libraries do it right. Most libraries want to do too much and others only offer visual separation of the language from the template, but still use logic within templates. Of course, I'm not omniscient and mostly keep to my world of PHP and JavaScript, so if there are viable alternatives for other languages, please let me know. In any case, Mustache does a few important things right:

1. Clear separation of view logic from the template

Mustache eliminates use of logical control structures like if, for or switch statements in templates by only allowing tags that are eventually replaced by a value (empty or non-empty) or a series of values. At first this might seem very restrictive, but it enforces clear exclusion of logic from templates, what ultimately leads to very clean and easy maintainable applications.

The restrictive nature of Mustache templates might lead to situations where Mustache seems to lack the appropriate functionality to display the desired data. Usually, this means code needs to be refactored instead. Mustache sets clear boundaries between handling and displaying data, which keeps us programmers from choosing the easy (but wrong) route.

2. Available for a wide range of languages

Most templating libraries can only be used for one programming language. Switching from language to language would require different libraries with probably different rules for handling and displaying data. Mustache can be used with PHP, Ruby, JavaScript, C++, Android, etc. etc. The list of supported languages is endless. It's not uncommon to use different languages in an application, so using Mustache will keep templates consistent between languages.

3. Very lightweight and unobtrusive

'Lightweight' and 'unobtrusive' seem like mandatory keywords for any application these days, but they apply for Mustache. It does exactly what it needs to, without adding bloat like date or math helpers. Taking Mustache for PHP as an example, only one file of around 24 kB is needed to implement Mustache in any PHP project. Furthermore, the Mustache class can easily be extended to abstract the implementation of Mustache entirely from the PHP application or provide extra functionality.

Small example

Mustache is very easy to learn using the straightforward documentation so I will not duplicate it here. Instead I will illustrate Mustache with a small example which uses the actual template I use for listing articles in the archive:

{{#articles}} 
  <li class="article">
    <div class="category">{{category}}</div> 
    <div class="title"><a href="{{uri}}" title="{{title}}">{{title_short}}</a></div>
    <div class="date">{{time}}</div> 
  </li>
{{/articles}}
{{^articles}}
  <li class="no-article">No articles found here</li>
{{/articles}}
{{> pagination}}

Every Mustache tag starts and ends with double curly brackets. Of course, it is possible to change the delimiters if needed. For every {{tag}} a variable, function or key with the same name will be used to change the tag to the desired output after rendering the template. If the corresponding variable is empty or non-existent, nothing will be rendered.

Sections are blocks which are rendered once or multiple times, depending on the value of the corresponding variable. Sections are denoted between tags with a starting symbol # and an ending symbol /. Everything between {{#section}} and {{/section}} gets rendered once with non-empty, single values and multiple times when dealing with an array. Of course, the whole section is neglected if the variable is empty or non-existent. In the example, a list of articles is created using the articles array with each entry having a category, title, time and uri.

If it's necessary to create output even when a section variable is empty or non-existent, tags with the same name starting with ^ and ending / can be used. Everything between these tags will get rendered if the section variable has no value. The example shows the use of these tags by outputting a message when there are no articles to list.

Finally, {{> pagination}} is a special tag called a partial that loads the contents of an external file. In this case the pagination.mustache file is called and rendered in place of this tag. Partials will inherit the variables of the parent template, so any tag in the main template can be reused in the included partial.

Closing comments

The simple example illustrates the major features of Mustache. It keeps templates clean by omitting the use of control structures in favor of simple single variables or repeating sections. Mustache does nothing special, but exactly what it needs to: omit logic from templates. It's not rocket science, but it will make projects a little less messy.

References

blog comments powered by Disqus