Handlebars e Nodejs su AWS Lambda

Programming code on a monitor.  - coding - Handlebars e Nodejs su AWS Lambda

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.