
Product
Unify Your Security Stack with Socket Basics
A single platform for static analysis, secrets detection, container scanning, and CVE checks—built on trusted open source tools, ready to run out of the box.
Mustachio is a pull streaming implementation of the Mustache templating language. It is fully compliant with version 1.1 of the Mustache spec.
const mustachio = require('mustachio');
const mu = mustachio.resolver();
mu("demo", { name: "World" }).stream().pipe(process.stdout);
And then, in a directory templates
, create the file demo.mustache
:
Hello, {{name}}!
Running this program outputs:
Hello, World!
If you want to use this together with Express, see mustachio-middleware.
Mustachio is streaming, whereas other templating engines usually are blocking. Traditionally, when serving a web request, the control flow is a sequence of three discrete steps:
In this model, no output can happen before the rendering is finished, and no rendering or output can happen before all the data has been collected. This is often good enough! However, a streaming model offers greater flexibility, can give better performance and it can be a better fit in an otherwise asynchronous environment such as node.js.
In Mustachio these three steps happen interleaved, in a streaming fashion. This means rendering can proceed as soon as the relevant data becomes available. Consequently, Mustachio will be able to respond immediately to many requests instead of waiting until the last bit of data trickles in. It also means flow control works, so rendering and gathering of input data can be suspended when the client can not keep up. This frees up resources for handling other requests.
The examples directory contains examples that highlight different qualities of the streaming model:
const mustachio = require('mustachio');
const template = mustachio.string("Hello, {{name}}\n");
const rendering = template.render({ name: "World" });
Stream render:
rendering.stream().pipe(process.stdout);
Render to string:
rendering.string().then(result => console.log(result));
const resolver = mustachio.resolver();
const rendering = resolver("template-name", { name: "World" });
This rendering
object has stream()
and string()
methods just like the
rendering
object above that we got from the template string.
The resolver uses the template ID you give in to locate a file in the file
system, under the directory templates
in your project directory. It looks for
files with file extensions .mustache
, .mu
, .mu.html
and .html
in that
order. The same mechanism is used to resolve partial includes.
When using the resolver, the compiled template is cached in memory and reused when rendering the same template again. Additionally, a file system watcher is set up to invalidate the cache whenever the template file is edited.
You can customize the base directory for templates and the file name suffixes used for resolving partials by passing a configuration object to the resolver:
const resolver = mustachio.resolver({
root: path.join(__dirname, "my-templates"),
suffixes: [ ".my.oh.my" ]
});
To get other behaviour and even resolve partials from other sources than the file system (such as the database, or HTTP calls), pass a custom partials resolver object:
const resolver = mustachio.resolver({
partialsResolver: new CustomPartialsResolver()
});
See partials for details.
When using a template string, partials will by default not be resolved. To
enable partials resolving for such templates, pass a partials resolver to the
render
function:
template.render(data, partialsResolver);
As a special concern, it is possible to explicitly flush the render buffer during rendering. Mustachio offers two ways of doing this:
{{_flush}}
tag in the template. Note that if your data
object includes data named _flush
it overrides the flush functionstream.flush()
in the code. It returns a Promise
, and when this
resolves, the render buffer has been flushedSee the React example for more about both methods.
data
objectThese are the types of values you can put in the data
object: Fundamental
types, objects, arrays,
functions, generator functions,
promises, text streams and object mode
streams.
The power of Mustachio comes from combining these building blocks. It works perfectly well to specify a function that returns a promise which resolves to a generator that yields functions which ... etc, etc. See the file-browser example for an effective use of this.
{
"number": 5.25,
"desc": "is a number.",
"true-bool": true
}
{{number}} {{desc}} {{#true-bool}}Yes!{{/true-bool}} {{true-bool}}
⇒ 5.25 is a number. Yes! true
{
"a": {
"b": 5,
"c": {
"d": 6
}
}
}
{{#a}}{{b}}, {{c.d}}{{/a}}
⇒ 5, 6
{ "a": [1, 2, 3] }
{{#a}}({{.}}){{/a}}
⇒ (1)(2)(3)
.
{
"a": () => 5
}
{{a}}
⇒ 5
Functions get called with the containing object as the this
argument:
{
"a": 5,
"b": function () { return this.a * 2; }
}
{{b}}
⇒ 10
Generator functions will be treated as arrays:
{
"a": function* () {
yield 0;
yield "is smaller than";
yield 1;
}
}
{{#a}}({{.}}){{/a}}
⇒ (0)(is smaller than)(1)
{
"a": new Promise((resolve, reject) => {
// Any asynchronous operation
require('fs').stat(__dirname, (stat, err) => {
if (err) reject(err);
else resolve(stat);
});
})
}
{{#a.isDirectory}}A directory!{{/a.isDirectory}}
⇒ A directory!
The file-browser example demonstrates use of promises as data.
A text stream can be interpolated, like a string:
{
"cmdline": require('fs').createReadStream('/proc/self/cmdline', 'utf8')
}
You ran: {{cmdline}}
⇒ You ran: node
Note that streams must have an encoding set, so they output text rather than binary data.
An object mode stream can be iterated over, like an array:
{
"objects": () => {
const objects = [ 1, 2, 3 ];
return new (require('stream')).Readable({
objectMode: true,
read() {
this.push(objects.length ? objects.shift() : null);
}
});
}
}
{{#objects}}({{.}}){{/objects}}
⇒ (1)(2)(3)
The postgres-query-stream example demonstrates use of object mode streams.
FAQs
A pull streaming Mustache engine
We found that mustachio demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
A single platform for static analysis, secrets detection, container scanning, and CVE checks—built on trusted open source tools, ready to run out of the box.
Product
Socket is launching experimental protection for the Hugging Face ecosystem, scanning for malware and malicious payload injections inside model files to prevent silent AI supply chain attacks.
Research
/Security News
The Socket Threat Research Team uncovered a coordinated campaign that floods the Chrome Web Store with 131 rebranded clones of a WhatsApp Web automation extension to spam Brazilian users.