I\'m new to Mustache.
Many templating languages (e.g., Django / Jinja) will let you extend a \"parent\" template like so...
I wrote a short code to enable extend and create layouts. .
If you don't want to copy/paste the header/footer, or maybe an menu bar that is repeated in all admin sub sections,
each time you render a page/view, you just need to use the function: build
of the followed class, that you can use as utils module
class MustacheLayout {
constructor() {
if (!MustacheLayout.instance) {
MustacheLayout.instance = this;
}
return MustacheLayout.instance;
}
async build(...layers) {
let previousLayer = '';
let combinedLayout = '';
for (const layer of layers) {
const { name: layerName } = layer;
let { data: layerData } = layer;
if (!layerData) layerData = {};
layerData.child = previousLayer;
combinedLayout = await this.renderHtml(layerName, layerData);
previousLayer = combinedLayout;
}
return combinedLayout;
}
renderHtml(viewName, data) {
return new Promise((resolve, reject) => {
this.app.render(viewName, data, (error, html) => {
if (error) reject(error);
resolve(html);
});
});
}
setExpressApp(expressApp) {
this.app = expressApp;
}
}
module.exports = new MustacheLayout();
//import the class const mustacheLayout = require('') //
const app = express();;
mustacheLayout.setExpressApp(app);
Put all the layer in the build function as parameters,
warning: - you need to respect order, from the smallest layout to the biggest (base.html) - data properties should be named as in the view
const layout = require('mustache-layout');
router.get('/edit', async (_, res) => {
const user = 'admin'
const html = await layout.build(
{ name: 'admin/edition/editor.view.html', data: { user } },
{ name:'layout/base.view.html' }
)
return res.send(html);
});
warning You need to use the keyword
child
in layout view pages. don't forget triple braces {{{ }}}
Use your passed data here
{{ user }}
{{ > layout/header.view }}
{{{ child }}}
{{ > layout/footer.view }}
If you need the package version of this code check mustache-layout-s