{

Javascript Template Engine(s)

I motori di template javascript sono esattamente quello che uno si aspetta che siano, cioè permettono di riutilizzare porzioni di testo, generalmente HTML, inframmezzate a dati. Mentre il testo rimane invariato, i dati possono essere diversi ad ogni chiamata. Si implemeta in questo modo il pattern MVC, Model-View-Controller per una separazione netta tra i dati e come questi vengono presentati.
Subito un esempio per chiarire partendo dal template:

<h1>{TITOLO}</h1>
<p>{TESTO}</p>

Se sostituiamo {TITOLO} con, ad esempio, "Javascript" e {TESTO} con, sempre ad esempio, "Linguaggio interpretato dinamicamente" il risulato è ovviamente:

<h1>Javascript</h1>
<p>Linguaggio interpretato dinamicamente</p>

Ora, se per pubblicare il prossimo articolo teniamo lo stesso HTML e cambiamo titolo e testo, per esempio rispettivamente con "Java" e "Linguaggio interpretato staticamente", il risultato è:

<h1>Java</h1>
<p>Linguaggio interpretato staticamente</p>

Infine, se volessimo modificare l'HTML sostituendo, per esempio, il tag p con un div, basterà modificare un solo file, quello del template.

Finora semplicemente abbiamo visto un utilizzo generico. Nel caso specifico vediamo come funziona per un Template Engine in javascript.

L'implementazione che ho deciso di utilizzare è doU.js di Laura Doktorova. Le ragioni sono presto dette: semplice, configurabile e, soprattutto, funziona.

Ma andiamo con ordine.

  1. Perché un motore in javascript
    Per ragioni di performance e di sicurezza innanzitutto. Nel progetto mi serve un motore di templating per le API pubbliche; non volendo dare la possibilità di utilizzare le API server side direttamente del progetto core, per ragioni di sicurezza, non rimanevano che poche strade:
    1. un sottoinsieme di classi e metodi java in cui però dovevo stare attento che nel codice di terze parti non si utilizzassero chiamate a metodi statici o si facesse uso della reflection
    2. utilizzare un linguaggio intermedio, sempre server side, controllato da un interprete interno
    3. pubblicare solo i dati essenziali e rimandare il tutto sul client

    Neanche a dirlo ho scelto la terza strada. In questo modo non devo curarmi neanche di controllare eventuali condizioni di lock o loop infiniti nel codice di terze parti.

  2. Quando utilizzarlo
    A parte le sovracitate condizioni di sicurezza, tutte le volte in cui è possibile demandare l'elaborazione al client senza inficiare le funzionalità dell'applicativo. Uno dei motivi per cui ho scelto doU.js è proprio nelle performance. In questo senso è possibile utilizzare il motore di templating anche per funzionalità interne, non per forza per le API pubbliche.
  3. Come utilizzarlo
    Per l'implementazione specifica rimando alla documentazione originale, qui mi concentro solo su come ho deciso di esporre i template.
    Nel mio caso permetto ad alcuni utenti preconfigurati di registrare il template su database, eventualmente indicando a quali gruppi applicativi è indirizzato. Sempre per ragioni di sicurezza ogni template viene esposto anche nella pagina del suo creatore; in questo modo l'utente, se maleintenzionato, si mangia il suo stesso pane (es. un loop infinito che blocca la pagina). Ovviamente oltre al template deve indicare quale è il set di dati che servono al template stesso; il set è predefinito da me all'interno del progetto ed è l'unico punto in cui occorre prestare attenzione a quali dati esporre.

Chiudo questa pagina con due note, una specifica dell'implementazione ed una di scelta progettuale.

doU.js permette cicli, ma si attende i dati in formato JSON. Per ovviare al caso in cui ritorno una lista trasformo l'array in un JSON con la proprietà length ed un attributo per ogni item della lista; il nome dell'attributo corrisponde all'indice, ovviamente castato a stringa altrimenti avrei errore.

Per scelta progettuale ho deciso di esporre i dati utilizzando DWR che permette di mappare classi java direttamente nella pagina attraverso chiamate AJAX asincrone. La sicurezza è allora doppia perché espongo solo le classi ed i bean i cui dati sono veramente pubblici. Per esempio non espongo mai l'oggetto java User perché contiene anche un campo password, esporrò piuttosto l'oggetto UserModel che espone solo il nome e cognome dell'utente ed il suo indirizzo email, che nel mio caso è pubblico. Per comodità UserModel ha un membro interno di tipo User che uso come delegate per il sottoinsieme di attributi che voglio esporre.

Quello che ho presentato in maniera molto veloce è frutto di uno studio magari non lunghissimo, ma certamente inteso in cui ho preso in considerazione diverse strade, tutte testate fin dove potevo, tra cui Mozilla Rhino, configurazioni custom di freemarker, di Velocity, altri motori di templating sia server, sia client, ed anche la possibilità di integrare altri linguaggi come python o php in un progetto java, sempre con l'intento di esporre solo l'essenziale.
Il risultato mi è sembrato in equilibrio per performance, sicurezza ed omogeneità di tecnologie rispetto ai desiderata del progetto base. Occorre infatti imparare solo una semplice sintassi, quella richiesta da doU.js, lasciando inalterate le tecnologie a supporto, con buona pace di tutti i programmatori del team.

Realizzato con Drupal, un sistema open source per la gestione dei contenuti