mustache -Logic-less templates.
A typical Mustache template:
Hello {{name}}You have just won {{value}} dollars!{{#in_ca}}Well, {{taxed_value}} dollars, after taxes.{{/in_ca}}Given the following hash:
{ "name": "Chris", "value": 10000, "taxed_value": 10000 - (10000 * 0.4), "in_ca": true}Will produce the following:
Hello ChrisYou have just won 10000 dollars!Well, 6000.0 dollars, after taxes.Mustache can be used for HTML, config files, source code -anything. It works by expanding tags in a template using valuesprovided in a hash or object.
We call it "logic-less" because there are no if statements, elseclauses, or for loops. Instead there are only tags. Some tags arereplaced with a value, some nothing, and others a series ofvalues. This document explains the different types of Mustache tags.
The Mustache language has aformal specification. The currentmanpage reflects version 1.3.0 of the specification, including theofficial-but-optional extensions for lambdas and inheritance.
Tags are indicated by the double mustaches.{{person}} is a tag, asis{{#person}}. In both examples, we'd refer toperson as the keyor tag key. Let's talk about the different types of tags.
The most basic tag type is the variable. A{{name}} tag in a basictemplate will try to find thename key in the current context. Ifthere is noname key, the parent contexts will be checked recursively.If the top context is reached and thename key is still not found,nothing will be rendered.
All variables are HTML escaped by default. If you want to return raw contentswithout escaping, use the triple mustache:{{{name}}}.
You can also use& to return its raw contents:{{& name}}. This may beuseful when changing delimiters (see "Set Delimiter" below).
By default a variable "miss" returns an empty string. This can usuallybe configured in your Mustache library. The Ruby version of Mustachesupports raising an exception in this situation, for instance.
Template:
* {{name}}* {{age}}* {{company}}* {{{company}}}Hash:
{ "name": "Chris", "company": "<b>GitHub</b>"}Output:
* Chris** <b>GitHub</b>* <b>GitHub</b>Dotted Names
If thename contains dots, it is split on the dots to obtain multiplekeys. The first key is looked up in the context as described above. If itis found, the next key is looked up within the previous result. This isrepeated until a key is not found or until the last key is found. Thefinal result is interpolated as above.
Template:
* {{client.name}}* {{age}}* {{client.company.name}}* {{{company.name}}}Hash:
{ "client": { "name": "Chris & Friends", "age": 50 }, "company": { "name": "<b>GitHub</b>" }}Output:
* Chris & Friends*** <b>GitHub</b>Implicit Iterator
As a special case, if thename consists of only a dot and nothing else,the value that is the current context is interpolated as a whole. Thisis especially useful if the parent context is a list; seeSectionsbelow.
Template:
* {{.}}Current context:
"Hello!"Output:
* Hello!Lambdas
If any value found during the lookup is a callable object, such as afunction or lambda, this object will be invoked with zero arguments. Thevalue that is returned is then used instead of the callable object itself.
Anoptional part of the specification states that if the final key inthename is a lambda that returns a string, then that string should berendered as a Mustache template before interpolation. It will be renderedusing the default delimiters (seeSet Delimiter below) against thecurrent context.
Template:
* {{time.hour}}* {{today}}Hash:
{ "year": 1970, "month": 1, "day": 1, "time": function() { return { "hour": 0, "minute": 0, "second": 0 } }, "today": function() { return "{{year}}-{{month}}-{{day}}" }}Output:
* 0* 1970-1-1Sections render blocks of text zero or more times, depending on thevalue of the key in the current context.
Lookup of dotted names works in the same way as with variables, except forslightly different treatment of lambdas. More on this below.
A section begins with a pound and ends with a slash. That is,{{#person}} begins a "person" section while{{/person}} ends it.
The behavior of the section is determined by the final value of the keylookup.
False Values or Empty Lists
If theperson key exists and has a value of false or an emptylist, the HTML between the pound and slash will not be displayed.
Template:
Shown.{{#person}} Never shown!{{/person}}Hash:
{ "person": false}Output:
Shown.Non-Empty Lists
If theperson key exists and has a non-false value, the HTML betweenthe pound and slash will be rendered and displayed one or more times.
When the value is a non-empty list, the text in the block will bedisplayed once for each item in the list. The context of the blockwill be set to the current item for each iteration. In this way we canloop over collections.
Template:
{{#repo}} <b>{{name}}</b>{{/repo}}Hash:
{ "repo": [ { "name": "resque" }, { "name": "hub" }, { "name": "rip" } ]}Output:
<b>resque</b> <b>hub</b> <b>rip</b>The same effect as above can be obtained without nested objects, by usingthe implicit iterator (seeVariables above).
Template:
{{#repo}} <b>{{.}}</b>{{/repo}}Hash:
{ "repo": ["resque", "hub", "rip"]}Output:
<b>resque</b> <b>hub</b> <b>rip</b>Lambdas
When any value found during the lookup is a callable object, such as afunction or lambda, the object will be invoked and passed the block oftext. The text passed is the literal block, unrendered.{{tags}} willnot have been expanded.
Anoptional part of the specification states that if the final key inthename is a lambda that returns a string, then that string replacesthe content of the section. It will be rendered using the same delimiters(seeSet Delimiter below) as the original section content. In this wayyou can implement filters or caching.
Template:
{{#wrapped}}{{name}} is awesome.{{/wrapped}}Hash:
{ "name": "Willy", "wrapped": function(text) { return "<b>" + text + "</b>" }}Output:
<b>Willy is awesome.</b>Non-False Values
When the value is non-false but not a list, it will be used as thecontext for a single rendering of the block.
Template:
{{#person?}} Hi {{name}}!{{/person?}}Hash:
{ "person?": { "name": "Jon" }}Output:
Hi Jon!An inverted section begins with a caret (hat) and ends with aslash. That is{{^person}} begins a "person" inverted section while{{/person}} ends it.
While sections can be used to render text zero or more times based on thevalue of the key, inverted sections may render text once basedon the inverse value of the key. That is, they will be renderedif the key doesn't exist, is false, or is an empty list.
Template:
{{#repo}} <b>{{name}}</b>{{/repo}}{{^repo}} No repos :({{/repo}}Hash:
{ "repo": []}Output:
No repos :(Comments begin with a bang and are ignored. The following template:
<h1>Today{{! ignore me }}.</h1>Will render as follows:
<h1>Today.</h1>Comments may contain newlines.
Partials begin with a greater than sign, like{{> box}}.
Partials are rendered at runtime (as opposed to compile time), sorecursive partials are possible. Just avoid infinite loops.
They also inherit the calling context. Whereas in ERB you may havethis:
<%= partial :next_more, :start => start, :size => size %>Mustache requires only this:
{{> next_more}}Why? Because thenext_more.mustache file will inherit thesize andstart methods from the calling context.
In this way you may want to think of partials as includes, or templateexpansion, even though it's not literally true.
For example, this template and partial:
base.mustache:<h2>Names</h2>{{#names}} {{> user}}{{/names}}user.mustache:<strong>{{name}}</strong>Can be thought of as a single, expanded template:
<h2>Names</h2>{{#names}} <strong>{{name}}</strong>{{/names}}Dynamic Names
Partials can be loaded dynamically at runtime using Dynamic Names; anoptional part of the Mustache specification which allows to dynamicallydetermine a tag's content at runtime.
Dynamic Names consists of an asterisk, followed by a dotted name which followsthe same notation and the same resolution as in an variable tag. That is{{>*dynamic}}. It can be thought as the followinghypothetical tag(which isnot allowed!):{{>{{dynamic}}}}.
Templates:
main.mustache:Hello {{>*dynamic}}world.template:everyone!Hash:
{ "dynamic": "world"}Output:
Hello everyone!A block begins with a dollar and ends with a slash. That is,{{$title}}begins a "title" block and{{/title}} ends it.
Blocks mark parts of the template that may be overridden. This can be donewith a block of the same name within a parent section in the callingtemplate (seeParents below). If not overridden, the contents of ablock render just as if the{{$title}} and{{/title}} tags weren'tthere.
Blocks could be thought of as template parameters or as inline partialsthat may be passed to another template. They are part of the optionalinheritance extension.
Templatearticle.mustache:
<h1>{{$title}}The News of Today{{/title}}</h1>{{$body}}<p>Nothing special happened.</p>{{/body}}Output:
<h1>The News of Today</h1><p>Nothing special happened.</p>A parent begins with a less than sign and ends with a slash. That is,{{<article}} begins an "article" parent and{{/article}} ends it.
Like an{{>article}} partial, a parent lets you expand another templateinside the current one. Unlike a partial, a parent also lets you overrideblocks of the other template.
Blocks within a parent can again be overridden by another includingtemplate. Other content within a parent is ignored, like comments.
Template:
{{<article}} Never shown {{$body}} {{#headlines}} <p>{{.}}</p> {{/headlines}} {{/body}}{{/article}}{{<article}} {{$title}}Yesterday{{/title}}{{/article}}Hash:
{ "headlines": [ "A pug's handler grew mustaches.", "What an exciting day!" ]}Output, assuming thearticle.mustache from before:
<h1>The News of Today</h1><p>A pug's handler grew mustaches.</p><p>What an exciting day!</p><h1>Yesterday</h1><p>Nothing special happened.</p>Dynamic Names
Some mustache implementations may allow the use of Dynamic Names inparent tags, similar to dynamic names in partials. Here's an example ofhow Dynamic Names in parent tags work.
Templates:
{{!normal.mustache}}{{$text}}Here goes nothing.{{/text}}{{!bold.mustache}}<b>{{$text}}Here also goes nothing but it's bold.{{/text}}</b>{{!dynamic.mustache}}{{<*dynamic}} {{$text}}Hello World!{{/text}}{{/*dynamic}}Hash:
{ "dynamic": "bold"}Output:
<b>Hello World!</b>Set Delimiter tags start with an equal sign and change the tagdelimiters from{{ and}} to custom strings.
Consider the following contrived example:
* {{default_tags}}{{=<% %>=}}* <% erb_style_tags %><%={{ }}=%>* {{ default_tags_again }}Here we have a list with three items. The first item uses the defaulttag style, the second uses erb style as defined by the Set Delimitertag, and the third returns to the default style after yet another SetDelimiter declaration.
According toctemplates, this "is useful for languages like TeX, wheredouble-braces may occur in the text and are awkward to use formarkup."
Custom delimiters may not contain whitespace or the equals sign.
Mustache is Copyright (C) 2009 Chris Wanstrath
Original CTemplate by Google
mustache(1),http://mustache.github.io/