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.