A Dart library to parse and render mustache templates.
See the mustache manual for detailed usage information.
This library passes all mustache specification tests.
import 'package:mustache/mustache.dart'; main() { var source = ''' {{# names }} <div>{{ lastname }}, {{ firstname }}</div> {{/ names }} {{^ names }} <div>No names.</div> {{/ names }} {{! I am a comment. }} '''; var template = new Template(source, name: 'template-filename.html'); var output = template.renderString({'names': [ {'firstname': 'Greg', 'lastname': 'Lowe'}, {'firstname': 'Bob', 'lastname': 'Johnson'} ]}); print(output); }
A template is parsed when it is created, after parsing it can be rendered any number of times with different values. A TemplateException is thrown if there is a problem parsing or rendering the template.
The Template contstructor allows passing a name, this name will be used in error messages. When working with a number of templates, it is important to pass a name so that the error messages specify which template caused the error.
By default all output from {{variable}}
tags is html escaped, this behaviour can be changed by passing htmlEscapeValues : false to the Template constructor. Also see the {{{triple mustache}}}
tag, and unescaped variable tag {{&unescaped}}
.
This library uses mirrors. When compiling with dart2js you will need to pass the experimental mirrors flag. You also need to mark any objects which will be rendered with the @mustache annotation. There is also another version of this library available which doesn't use mirrors.
Tag names may only contain the characters a-z, A-Z, 0-9, underscore, period and minus. Other characters in tags will cause a TemplateException to be thrown during parsing.
During rendering variables which are missing will cause a TemplateException will be thrown.
var t = new Template('{{ author.name }}'); var output = template.renderString({'author': {'name': 'Greg Lowe'}});
var partial = new Template('{{ foo }}', name: 'partial'); var resolver = (String name) { if (name == 'partial-name') { // Name of partial tag. return partial; } }; var t = new Template('{{> partial-name }}', partialResolver: resolver); var output = t.renderString({'foo': 'bar'}); // bar
var t = new Template('{{# foo }}'); var lambda = (_) => 'bar'}; t.renderString({'foo': lambda); // bar
var t = new Template('{{# foo }}hidden{{/ foo }}'); var lambda = (_) => 'shown'}; t.renderString({'foo': lambda); // shown
var t = new Template('{{# foo }}oi{{/ foo }}'); var lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>'}; t.renderString({'foo': lambda); // <b>OI</b>
var t = new Template('{{# foo }}{{bar}}{{/ foo }}'); var lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>'}; t.renderString({'foo': lambda, 'bar': 'pub'); // <b>PUB</b>
var t = new Template('{{# foo }}{{bar}}{{/ foo }}'); var lambda = (LambdaContext ctx) => '<b>${ctx.renderString().toUpperCase()}</b>'}; t.renderString({'foo': lambda, 'bar': 'pub'); // <b>PUB</b>
In the following example LambdaContext.renderSource(source)
re-parses the source string in the current context, this is the default behaviour in many mustache implementations. Since re-parsing the content is slow, and often not required, this library makes this step optional.
var t = new Template('{{# foo }}{{bar}}{{/ foo }}'); var lambda = (LambdaContext ctx) => ctx.renderSource(ctx.source + '{{cmd}}')}; t.renderString({'foo': lambda, 'bar': 'pub', 'cmd': 'build'); // pub build