The Ultimate Mustache Tutorial

April 2020

Learning Mustache is a lot faster if you understand properly what it's all about and learn the underlying concepts. You'll grasp a firmer understanding of Mustache by going through this tutorial, than by directly diving into the official docs, which often seem confusing at first.

What is Mustache?

The first thing to learn is that Mustache is NOT a templating engine. Mustache is a specification for a templating language. This specification can be found here, but don't read that just yet. You're not ready yet.

The idea is, that you write templates that adhere to the Mustache specification, that then can be compiled / rendered to create an output.

What's a Templating Language and what's it for?

Let's say you want to send the same email to 100 people, except you want to personalize the salutation with their respective first names. You could replace the first name by some placeholder:

Dear *|FNAME|*

I hearby blablabla ...

Here I have invented (=stolen it from Mailchimp) a syntax for a placeholder: *|FNAME|*

The mustache syntax looks a bit different. This case would be covered by the following template:

Dear {{fname}}

I hearby blablabla ...

As you can see, in Mustache we have curly braces for placeholders, which look like a mustache when rotated 90 degrees clockwise:

Hence the name of the language. There's more to the Mustache than that, but before diving any deeper into the language, it's useful to first cover another concept.

By simply having specified a templating language and having written a template doesn't produce 100 emails for me. Much like with a programming language, just learning the language doesn't actually mean you know how to run a program. For example you might read in your first JavaScript tutorial that " var x = 5 + 3 ;" is JavaScript, but you might not know exactly how you could run the code. Similarly with Mustache, you might learn about the language in a tutorial, but have no idea how to actually convert your templates to an output. Or to put it differently: How the heck can I create my 100 emails from 1 single Mustache template? You'll need a ...

Templating Engine

So once a syntax aka. templating language is defined, you need a tool that fills the placeholders in the template(s) with actual data and produces an output. This is called a templating engine:

To strech this point again, Mustache is not the templating engine. It's the specification for how the template file must look like.

Or to come back to the example with programming languages. Mustache is the language. Not the execution environment. You can learn about the language in a book. But to actually use the language, you'll need a computer and something that can interpret and run your code. The programming language JavaScript, for example can be ran and interpreted by Firefox, Chrome, Microsoft Edge and Safari, but they all use a different underlying engine to interpret and run it.

What's the Templating Engine for Mustache?

Like for JavaScript there, isn't just one thing that can compile Mustache. There's a multitude of tools out there that can take a Mustache Template, some input data, and produce an output. The multitude of tools is actually overwhelming. There are tools that do their job well. And then there are obsolete ones that are badly maintained and don't actually adhere to the Mustache specification. So which one should you choose from the multitude of options? The answer is: It depends on where and how you want to use Mustache. I will make some examples here, but I encourage you not to get lost in the actual links to those tools, but rather stick with the tutorial. When you leave now, you'll be into the nitty gritty of how to use one tool without having the greater picture.

Example 1: You have a Java server and want to send out emails to users. So you use our Mustache Template from above for the emails and extend it a bit. So now you'd like to tell your Java code "hey, I've got a mustache template and 3 users that go by the name of ["Hans", "Gertrude", "Fritz"], can you send them a welcome mail"? Then your best bet would be to use the most popular Mustache Engine written in Java: https://github.com/spullara/mustache.java . Why? Because you have the data already in your Java code. The Mustache template file you can load through regular I/O:

// DOESN'T ACTUALLY WORK THAT WAY, BUT WAS EASIER TO ILLUSTRATE
String[] users = {"Hans","Gertrude","Fritz"};
for (String user : users) {
  String renderedEmail = mf.compile("emailTemplate.mustache", user);
  // ...then send email to user...
}

Example 2: You have a Python server and want to send an E-Mail. Pretty much the same as above, except that you'd use the most popular Mustache Engine written for Python: https://github.com/defunkt/pystache.

Example 3: You just want to print 100 personalized invitations to your birthday party, but have no idea about coding whatsoever (which is obvious, since coders don't have 100 friends). Then unfortunately Mustache is not a good choice for you, since literally all engines for Mustache are connected to a programming language. There isn't such a thing that takes an excel list of invitees plus a Mustache template and generates 100 pdfs out of it. At least I haven't found something like that. Even though in principle it would work since it's just a case of [Template + Input Data = Output] there just aren't enough people that want to build their birthday cards that way...

Actually, this example 3 was really educational. We've learned that all available Mustache engines are connected to programming languages. Which ones are the available languages?

Here's a screenshot from the official Mustache page answering that question:

Okay, that's quite a lot of implementations. As I mentioned, some are good, some are bad. For example, there was one listed for "node.js" which wasn't maintained and was quite buggy, while the one under "JavaScript" actually also supports node.js. They now removed the bad one from the list, but as you can see this list isn't the be-all end-all. Maybe some of the listed links are outdated. Maybe some other ones are not included. At the same time, it's still the best list that I'm aware of.

So now that we've covered the conceptual basics, we can dive deeper into the Mustache Templating language. But let's first repeat what we've learned so far:

Learning the Mustache Template Syntax

Now for the rest of the tutorial you have two choices. Either you select a templating engine from above and learn how it works. Then you can actually test the examples on your machine, which makes it a bit more tangible. But since Mustache is just a language, you might also be lying at a beach right now, slurping your drink, and reading the rest of the tutorial.

The Basics

We already have seen our very first template above, but let's repeat it in a similar fashion because it was so beautiful.

Mustache Template:

Hello {{planet}}

Input Data:

{
  "planet": "Earth"
}

We choose JSON to describe our data here, but this would depend on the engine you're using. If you throw the mustache template plus the input data at a templating engine, it should (if it's not buggy) produce the following output:

Hello Earth

So the templating engine replaces (also known as expands) the tags (the curly brace things) with what it finds in the input data. If in the template it's written: {{someVariableName}}, the engine will search the input data for the key "someVariableName" and replace the tag with the value it finds for this key. Here, "planet" was the lookup key and "Earth" was the value the engine found for this key.

Now, depending on your chosen templating engine, the output might be stored in a variable of your program or written to the filesystem. For example, the JavaScript mustache engine has two modes: Either it can be used as a command line tool to produce files, or it could be used to dynamically render html files.

Conditionals

In Mustache, there are no if and else statements and also no loops. That's why they call it logic-less templating. At least they're not directly represented as keywords in the templating language. It is however possible to conditionally show or hide a block of text. And this is how:

Mustache Template:

Hello
{{#myCondition}}
  la di da
{{/myCondition}}
Data:
{
  "myCondition": false
}
Output:
Hello

At first, this syntax might look a bit weird to you. But it get's clearer once we read those sections from the docs, which I have changed slightly:

[Mustache] works by expanding tags in a template using values provided in a hash or object. [...] A section begins with a pound and ends with a slash. That is, {{#person}} begins a "person" section while {{/person}} ends it. If the person key exists and has a value of false or an empty list, the [content] between the pound and slash will not be displayed. [...] If the person key exists and has a non-false value, the [content] between the pound and slash will be rendered and displayed.

Loops through Arrays / Lists

Loops are also not represented directly in the mustache language, but indirectly via the data and how the mustache specification specifies behaviour when the data is an array.

Data:

{
  "users": ["Hans", "Fritz", "Geraldine"]
}
Mustache Template:
{{#users}}
{{.}}
{{/users}}
Output:
Hans
Fritz
Geraldine
If you want all names on the same line, you'll have to write {{#users}}{{.}} {{/users}} on one line in the template (and put a space in there for legibility).

The elements could also be objects instead of strings, in which case access is given by just writing the property names into the braces:

Data:
{
  "users": [{
    "name": "Hans"
  }, {
    "name": "Fritz"
  }, {
    "name": "Geraldine"
  }]
}
Mustache Template:
{{#users}}
{{name}}
{{/users}}
Output:
Hans
Fritz
Geraldine

Using templates inside of templates: "Partials"

One Mustache template can load another template. The specification states that this should work with the syntax
I am a template and I'm loading
{{> template2 }}
and now I continue
This works fine as long as template2 doesn't require template1, then you'll get an infinite recursion which your templating engine can't handle.

Passing Data to Partials

Passing data to partials is actually a bit tricky and one of the things that took me the longest to figure out. It works like this:
{{#buttonOne}}
  {{> mybutton}}
{{/buttonOne}}
{{#buttonTwo}}
  {{> mybutton}}
{{/buttonTwo}}
and in the data you’d specify
{
  "buttonOne": {
    "title": "Cancel"
  },
  "buttonTwo": {
    "title": "Save"
  }
}
In the partial there could be the code
<button class="my-cool-button">{{title}}</button>
The result would print
<button class="my-cool-button">Cancel</button>
<button class="my-cool-button">Save</button>

You can think about it like this: The surrounding {{#buttonOne}}...{{/buttonOne}} is setting the context to buttonOne in the input data. Then the partial inherits this context and replaces the variable title accordingly.

Comments

Comments begin with an exclamation point and are ignored. The following template:

<h1>Hello{{! ignore me }}.</h1>
Will render as follows:
<h1>Hello.</h1>
Comments may contain newlines.

Further reading

There are some concepts we haven't discussed here, such as for example Lambdas. If you want to learn about those concepts, I suggest you head over to the Original Mustache Specs.

An Example with an Actual Templating Engine

So now that we've learned a bit about the mustache language, it is time that we also look at an example of a templating engine. After all, just knowing the language usually isn't your goal, you want to be able to use the language to get a job done. And the templating engine gets the job done, once you provide it with a template and the input data.

Let's take the JavaScript templating engine found here https://github.com/janl/mustache.js, since Mustache seems to be most commonly used together with JavaScript.

So you'd get started by installing the templating engine like this:

mkdir mustache-tutorial
cd mustache-tutorial
npm init

Hit enter a few times, then:

npm install mustache

Then you can create the template file called letter-template.mustache and put the following template in there:

I hereby greet all my friends.
{{#users}}
  Hello {{name}}
{{/users}}

Nice knowing y'all!

Now we also need a second file, that specifies who my friends are! So we'll put the friendlist from above in a JSON called friends.json

{
  "users": [{
    "name": "Hans"
  }, {
    "name": "Fritz"
  }, {
    "name": "Geraldine"
  }]
}

And now the final step. Combining the template and the data. If you look at the schematics above, this is where the templating engine comes into play. With the JavaScript engine, it'll now work like this:

npx mustache friends.json letter-template.mustache > letter.txt

Now if you look what you have produced (cat letter.txt), you'll see the following:

I hereby greet all my friends.
  Hello Hans
  Hello Fritz
  Hello Geraldine

Nice knowing y'all!

You'll notice, that all the "Hello ..." lines are indented by two spaces. That's because they are also indented in the template. So to get rid of those spaces, change the template to:

I hereby greet all my friends.
{{#users}
Hello {{name}}
{{/users}}

Nice knowing y'all!

Well, and that's it!

Summarized Learnings

Grasping the concepts at first isn't easy because there are so many different implementations of Mustache and they're often confused with the actual Mustache specification. Yet through a clear separation, the Mustache language can be learned independently, and then the skills can be used together with a carefully chosen engine (since not all of them are good or adhere to the official Mustache specs). Thanks for reading the tutorial, I hope you learned a lot, don't forget to subscribe if you're interested in Web Development and share the post with friends!

Dear Devs: You can help Ukraine🇺🇦. I opted for (a) this message and (b) a geo targeted message to Russians coming to this page. If you have a blog, you could do something similar, or you can link to a donations page. If you don't have one, you could think about launching a page with uncensored news and spread it on Russian forums or even Google Review. Or hack some russian servers. Get creative. #StandWithUkraine 🇺🇦
Dear russians🇷🇺. I am a peace loving person from Switzerland🇨🇭. It is without a doubt in my mind, that your president, Vladimir Putin, has started a war that causes death and suffering for Ukrainians🇺🇦 and Russians🇷🇺. Your media is full of lies. Lies about the casualties, about the intentions, about the "Nazi Regime" in Ukraine. Please help to mobilize your people against your leader. I know it's dangerous for you, but it must be done!