Helpers di Handlebars in Nodejs per template complessi
Mi sono ritrovato a dover creare delle pagine html statiche recuperando i dati da un database tramite la creazione di una funzione Lambda su AWS. La soluzione che mi è parsa subito la migliore è stata quella di scegliere di utilizzare la libreria https://handlebarsjs.com/ che permette la creazione di un template e la sostituzione all’interno di singoli riferimenti o di parti più complesse.
Non avendo mai utilizzato gli helpers di Handlebars, ho iniziato la ricerca online per trovare qualche suggerimento. Di seguito riporto i passaggi seguiti per l’utilizzo all’interno di una funzione Lambda, messi insieme sfruttando quanto trovato online e dopo alcuni ragionamenti personali.
Necessità:
- scrivere una funziona async/wait che recuperato un template, sostituisca tutte le occorrenze e restituisca un html usabile per essere salvato in un file html su S3
- utilizzare gli helpers per la sostituzione di occorrenze complesse, sia da dati statici (file json) sia da dati dinamici recuperati da database
Alla funzione, richiamata in modo asincrono, vengono passati i dati dinamici recuperati dal database. All’interno di un blocco try/catch richiama gli helpers e il template elabora i dati e restituisce un html pronto ad essere salvato su S3 per essere pubblicato online.
const document = fs.readFileSync('template-tpl.html', 'utf-8');
const menuJson = require("menu.json");
async function getHtmlPageContent(pack){
try {
require("hb-helpers.js")(handlebars, pack);
const template = handlebars.compile(document);
let data = {};
data.itemsMenu = menuJson;
const html = template(data);
return html;
} catch (error) {
console.log('HBS ERROR', error);
return context.fail(error);
}
}
Fuori dalla funzione, in fase di impostazione, avevo dichiarato due costanti: la prima contenente il template html, la seconda contenente la struttura json del menù. Per prima cosa nella funzione, richiamo un file js esterno contenente gli helpers:
require("hb-helpers.js")(handlebars, pack);
e gli passo l’oggetto handlebars (oggetto della libreria) e i valori dinamici ottenuti dal database utilizzati nell’helpers per la gestione delle lingue. Quindi compilo il template html nella costante template e imposto la variabile itemsMenu dell’oggetto data con i valori del json per costruire il menu.
const template = handlebars.compile(document);
let data = {};
data.itemsMenu = menuJson;
A questo punto fondo l’oggetto data con il template per ottenere l’html completo che la funzione restituirà.
const html = template(data);
return html;
Successivamente analizziamo nel dettaglio alcuni particolari dei singoli file utilizzati.
Template HTML – (template-tpl.html)
<div class="navbar-collapse collapse float-right nav-main-collapse">
<nav class="nav-main">
<ul id="topMain" class="nav nav-pills nav-main">
{{#each itemsMenu}}
{{menuItem}}
{{/each}}
</ul>
</nav>
</div>
Blocco html del menu contenente i tag di Handlebars per iterare sull’oggetto itemsMenu (variabile dell’oggetto data contenente il json), dove menuItem è l’oggetto che verrà utilizzato dall’helpers per la sostituzione con le singole voci di menu.
Helpers – (hb-helpers.js)
function hbsHelpers(hbs, pack) {
//MENU
hbs.registerHelper('menuItem', function() {
var text = hbs.escapeExpression(this.text),
liClass = hbs.escapeExpression(this.liClass),
href = hbs.escapeExpression(this.url),
aClass = hbs.escapeExpression(this.aClass),
spanClass = hbs.escapeExpression(this.spanClass);
return new hbs.SafeString(
'<li class="'+liClass+'"><a href="'+href+'" class="'+aClass+'"><span class="trn '+spanClass+'">'+text+'</span></a></li>'
);
});
}
module.exports = hbsHelpers;
La funzione hbsHelpers con la registrazione dell’helpers menuItem. Questo helper recupera dal json (oggetto data.itemsMenu) i valori per text, liClass, href, aClass e spanClass e li utilizza per la costruzione della voce di menu.
Json del menu – (menu.json)
[
{
"text": "HOME",
"icon": "",
"liClass": "",
"aClass": "",
"spanClass": "theme-color",
"url": "/index.html"
},
{
"text": "TOUR",
"icon": "",
"liClass": "",
"aClass": "",
"spanClass": "theme-color",
"url": "/tour.html"
}
]
Un semplicissimo json contenente i valori per la costruzione del menu.
In conclusione, sfruttando le potenzialità di Handlebars e dei suoi helpers, è possibile costruire un html partendo da un template complesso.