Template con Apache Velocity

Apache Velocity è un sistema di template semplice e veloce. In questo articolo vediamo le caratteristiche principali e come utilizzarlo con i principali framework MVC.

In molte occasioni, invece di reinventare la ruota, Velocity può essere utilizzato all’interno dei nostri programmi con estrema semplicità. Il principio di funzionamento di questa libreria è abbastanza simile a prodotti simili che permettono di creare template come JasperReport, FreeMarker etc. etc. Abbiamo un template, dove è presente un modello da restituire mischiato a delle variabili. A runtime passiamo questo template a Velocity, fornendo il valore di queste variabili e quindi avremo il risultato finale.

Apache Velocity

Primi template

Come sempre vediamo la stampa del classico Hello World utilizzando Velocity. Nel nostro progetto andremo a definire la seguente dipendenza Maven

Ora dobbiamo definire è un template che verrà utilizzato nel esempio

Il testo contiene una variabile, identificata dal prefisso $. Ora vediamo come utilizzare Velocity per richiamare il template helloword.vm e passargli la variabile $stringa

Il caricamento del file template avviene utilizzando il classpath, dove andremo a posizionare helloworld.vm. VelocityContext rappresenta invece la parte di dati che si possono associare al template e in questo caso andiamo ad aggiungere una semplice variabile “stringa”. Infine effettuiamo il merge tra context e template, riversando il risultato in uno StringWriter che poi potremo utilizzare per visualizzare il risultato.

E’ possibile istanziare l’engine di Velocity in due modi differenti, singleton o separate instance. Nel primo caso avremo una sola istanza nella nostra JVM, mentre nel secondo caso (come nell’esempio che abbiamo appena riportato) viene creata un’istanza specifica dell’engine. Quest’ultima modalità può essere utile quando abbiamo differenti modi d’utilizzo di Velocity all’interno del nostro programma, che vengono specificate attraverso il settaggio di alcune proprietà.

Altro caso comune è il modo differente in cui vengono reperiti i template. Nel caso primo esempio questi sono stati recuperati dal classpath ma ad esempio potremmo avere l’esigenza di caricarli dinamicamente perchè memorizzati su database. Nel prossimo esempio potete vedere utilizzare Velocity con un template recuperato da un InputStream

 

Direttive

All’interno dei template è possibile utilizzare una serie di direttive che ci permettono di manipolare i dati che dobbiamo visualizzare. Di seguito è riportata la lista delle direttive presenti in Velocity

  • #set() : definizione di variabili
  • #if() : espressione condizionale
  • #else : espressione condizionale
  • #elseif() : espressione condizionale
  • #end : espressione che permette di chiuderne un’altra aperta precedentemente (foreach,macro,if)
  • #foreach() : istruzione che permette di scorrere una lista di oggetti
  • #include() : include un’altra risorsa, in maniera statica
  • #parse() : include un’altra risorsa che può essere un template
  • #macro() : permette la definizione di macro che posso essere richiamate nel template

 

Per capire meglio alcune direttive vediamo subito un esempio di template dove ce ne sono diverse

All’inizio e alla fine del template sono presenti due direttive, parse e include, che aggiungono altre risorse. Nel caso di parse, la risorsa inclusa è a sua volta un template che verrà valutato. Successivamente c’è l’impiego dei costrutti condizionali if/else/elseif, che in questo caso vengono utilizzati per stampare una diversa frase in base al valore di una variabile. Infine c’è il foreach che come in Java ed altri linguaggi scorre una lista di oggetti e li stampa semplicemente. Di seguito il codice che possiamo utilizzare per passare i valori a questo template

Macro

Definire le macro all’interno dei template ci permette di avere raggruppate delle funzioni che è possibile richiamare. Questo può tornare utile quando appunto bisogna riutilizzare porzioni simili di codice per eseguire una certa operazione. Partiamo da un esempio in cui abbiamo una classe Utente con una serie di informazioni e una lista di questi utenti che dobbiamo visualizzare. Il codice Java potrebbe essere il seguente

All’interno del template dovremo scorrere la lista di utenti e visualizzare le informazioni. Per effettuare questa stampa di informazioni è possibile appunto utilizzare una macro, definita come nel seguente template

 

Spring MVC e Velocity

Velocity, come altri sistemi di template, può essere utilizzato nella generazione delle pagine all’interno di progetti web. All’interno della configurazione di Spring MVC dobbiamo andare ad aggiungere un nuovo resolver come riportato di seguito

Le viste che utilizzeranno il resolver di Velocity avranno un layout comune, layout.vm, che potrebbe essere quello riportato

$screen_content sarà popolato con il valore del template che utilizzeremo.

 

Struts e Velocity

Struts2 per quanto riguarda la parte di View, gestisce già per default Velocity. Infatti all’interno del file struts-default.xml è già configurato il return type relativo a Velocity. Quindi per gestire una vista con un template Velocity possiamo utilizzare semplicemente questa definizione