Assuming you use cool mustache.js in many places. Recently you have started to use lit-html, which is in at least some scenarios even cooler ([1], [2]).
But now you are stuck with two different render engines and have to load and manage both of them - that is annoying. In the case you cannot simply rewrite all your templates (e.g. when some of them are provided by external users), you might be stuck with this situation for a long time.
For the rescue this little library transforms a valid mustache.js
-template into a valid lit-html
-template.
import { html, render } from 'lit-html';
import { unsafeHTML } from 'lit-html/directives/unsafe-html'
import createTransformer from 'lit-transformer';
const mustache2litHtml = createTransformer(html, unsafeHTML);
const renderTemplate = mustache2litHtml('<div>Hello {{who}}!</div>');
render(renderTemplate({ who: 'world' }), document.getElementById('basic'));
Template type | Supported | Note |
---|---|---|
Variables {{var}} , {{{var}}} |
✔ | {{&var}} is not supported |
Sections {{#var}}...{{/var}} |
✔ | function as var is not supported |
Functions | ✗ | |
Inverted Sections {{^var}}...{{/var}} |
✔ | |
Comments {{!...}} |
✔ | |
Partials | ✗ | |
Custom Delimiters {{=<% %>=}} |
✔ |
It is easy to customize the set of template tags:
import { html, render } from 'lit-html';
import { unsafeHTML } from 'lit-html/directives/unsafe-html.js'
import createTransformer from 'lit-transformer/src/lit-transformer.js';
import transformVariable from 'lit-transformer/src/transformers/variable.js';
import unsafeVariableTransformer from 'lit-transformer/src/transformers/unsafeVariable.js';
import sectionTransformer from 'lit-transformer/src/transformers/section.js';
import invertedSectionTransformer from 'lit-transformer/src/transformers/invertedSection.js';
import commentTransformer from 'lit-transformer/src/transformers/comment.js';
import customDelimiterTransformer from 'lit-transformer/src/transformers/customDelimiter.js';
const mustache2litHtml = createTransformer({
html,
delimiter: { start: '{{', end: '}}' },
transformVariable,
transformers: {
// out of the box transformers:
unsafeVariable: unsafeVariableTransformer(unsafeHTML),
section: sectionTransformer(),
invertedSection: invertedSectionTransformer(),
comment: commentTransformer(),
customDelimiterTransformer: customDelimiterTransformer(),
// customized transformers:
customXandY: {
test: remainingTmplStr => remainingTmplStr[0] === '+',
transform: (remainingTmplStr, config) => {
const indexOfEndDelimiter = remainingTmplStr.indexOf(config.delimiter.end)
return {
remainingTmplStr: remainingTmplStr.substring(indexOfEndDelimiter + config.delimiter.end.length),
insertionPoint: ctx => ctx.x + ctx.y,
};
},
},
customUnescapedVariable: {
test: remainingTmplStr => remainingTmplStr[0] === '&',
transform: (remainingTmplStr, config) => {
return config.transformers.unsafeVariable.transform(insert3rdBraceForUnsaveVariable(remainingTmplStr), config);
function insert3rdBraceForUnsaveVariable(remainingTmplStr) {
const i = remainingTmplStr.indexOf(config.delimiter.end);
return remainingTmplStr.substring(0, i) + '}' + remainingTmplStr.substring(i);
}
},
},
},
});
const renderData = mustache2litHtml('<div>Hello {{&who}}! {{x}} + {{y}} = {{+}}</div>');
const data = { who: '<b>customized world</b>', x: 1, y: 2 };
render(renderData(data), document.getElementById('customized'));