Micro mustache-style template parser
Download the CJS, ESM, UMD versions or install via NPM:
npm install @ryanmorr/stache
Similar to how tagged templates parse template literals, stache parses a mustache string template into an array of static strings and an array of the interpolated values:
import stache from '@ryanmorr/stache';
const tpl = stache('{{firstName}} {{lastName}}');
const [strings, values] = tpl({
firstName: 'John',
lastName: 'Doe'
});
console.log(strings); //=> ["", " ", ""]
console.log(values); //=> ["John", "Doe"]
In addition to simple value interpolation, loops, if/else statements, and expressions are also supported:
const tpl = stache(`
{{each items as item, index}}
{{if index === 0}}
{{ item + 10 }}
{{else if index === 1}}
{{ item - 10 }}
{{else}}
{{ item }}
{{/if}}
{{/each}}
`);
const [strings, values] = tpl({
items: [10, 20, 30]
});
console.log(strings); //=> ["", "", "", ""]
console.log(values); //=> [20, 10, 30]
You can use the arrays of strings and values to formulate your own custom templating solution. For example, here's a basic string templating engine:
import stache from '@ryanmorr/stache';
function createTemplate(source) {
const tpl = stache(source);
return (data) => {
const [strings, values] = tpl(data);
return strings.reduce((acc, str, i) => acc + (values[i - 1]) + str);
};
}
const tpl = createTemplate(`
<ul>
{{each items as item}}
<li>{{item}}</li>
{{/each}}
</ul>
`);
const html = tpl({
items: ['foo', 'bar', 'baz']
});
console.log(html); //=> "<ul><li>foo</li><li>bar/li><li>baz</li></ul>
You can also combine stache with a tagged template compatible parser for expanded functionality. The following uses htm for a hyperscript-based solution:
import htm from 'htm';
import stache from '@ryanmorr/stache';
const html = htm.bind((tag, props, ...children) => {
return {tag, props: props || {}, children};
});
function createTemplate(source) {
const tpl = stache(source);
return (data) => {
const [strings, values] = tpl(data);
return html(strings, ...values);
};
}
const tpl = createTemplate('<div id={{id}} onclick={{handler}}>{{content}}</div>');
const vnode = tpl({
id: 'foo',
content: 'bar',
handler: () => console.log('clicked')
});
console.log(vnode); //=> {tag: 'div', props: {id: 'foo', onclick: handler}, children: ['bar']}
This project is dedicated to the public domain as described by the Unlicense.