In quest’articolo parleremo di Jinja il motore di template usato nell’ecosistema Python. Creato nel 2008 da Armin Ronacher, lo stesso ideatore del micro framework Flask. Esso viene usato per creare documenti dinamici unendo modelli statici (templates) con dati variabili, le sue applicazioni le ritroviamo in particolare modo in applicativi web quali Flask, Bottle, Django e tool come Ansible e Pellican, ma non solo, lo si può utilizzare anche direttamente su programmi in ambiente Python. Spesso chiamato anche banalmente Jinja2 in riferimento alla sua versione di rilascio, ha lo scopo principale di dividere l’aspetto grafico dal codice logico, rendendo la struttura del programma più pulita e meglio mantenibile. Jinja è un progetto opensource, indipendente, e sempre in continuo aggiornamento, risulta essere sicuro, affidabile, mantenibile, ricco di funzionalità e semplice da usare. lo scopo è quello di unire modelli di testo e grafica ad una business logica che restituisce dati come variabili, liste, dizionari, oggetti, elementi Json. Con Jinja si possono creare documenti di testo o di markup quali Html, Json, Xml, Csv, Txt, Latex, ecc…
Cos’è un template
Prima di procedere con gli esempi e’ opportuno soffermarsi sul definire cos’e’ un template. Un template (sagoma, calco) è la struttura di un documento composto da righe di testo predefinite, situate in una determinata posizione, con spazzi vuoti da riempire con dati variabili. L’impaginazione del documento detto layout rimane invariato, cambiano solo i dati.
In Fig. 1 si può vedere un esempio di template con parti di testo predefinite e parti variabili. Nel campo web i template sono dei documenti di esempio per lo sviluppo di altre pagine web con grafiche e formattazione identiche ma con contenuti diversi. Adesso che abbiamo visto che cosa sono i template vediamo cosa fa Jinja. Jinja genera dei blocchi di testo dinamici in una struttura predefinita, quindi il tutto si basa su due grandi attori che sono il template e i dati. I template formati da grafiche, strutture predefinite con situati in essi dei segnaposto che andranno sostituiti dai dati. E i dati che possono essere delle semplici variabili, delle liste, dei dizionari o degli oggetti presi da un database, oppure documenti Json o di altro tipo, ci possono essere anche dati generati dinamicamente attraverso degli algoritmi.
La visualizzazione dei dati in un template è detta rendering. Jinja oltre che gestire il rendering dei dati ha anche altre funzionalità quali:
- Tag che contengono codice strutturato (strutture di controllo e cicli) ;
- L’ereditarietà dei template (il template inheritance) ;
- L’uso di Macros ;
- Un sistema di auto-escaping del codice ;
- Una Sandbox per rendere il codice più sicuro ;
- Filtri ;
- Test ;
- Un supporto Unicode .
Installazione
L’installazione di Jinja è molto semplice, basta aprire una shell e usare l’installer di python pip, digitando il seguente codice.
pip install jinja2
Ovviamente l’ installazione del package andrebbe fatta in un ambiente virtuale, per tenere i progetti ben separati tra loro, evitando conflitti tra versioni varie.
Esempi
Vediamo ora come utilizzare Jinja2 tramite alcuni esempi. Prima però vediamo un po’ come vengono definiti i segnaposto nel modello.
Per renderizzare semplici variabili bisogna inserire il dato dinamico tra doppie parentesi graffe {{}}
<p>Tra le parentesi graffe viene visualizzata la variabile {{miaVariabile}}</p>
Per usare strutture di controllo o cicli usare i seguenti tag di apertura e chiusure {% struttura %} {% endstruttura %}
{* struttura di controllo *}
{% if true %}
print("ok")
{% else %}
print("nok)
{% endif %}
{* ciclo for *}
{% for a in range(1,10) %}
print(a)
{% endfor %}
Per scrivere dei commenti usare il {* …commento… *}
Esempio di template base.
Vediamo come creare un template base. Dopo aver installato la libreria Jinja, creiamo una cartella con un nome a piacere, all’interno di essa creiamo un file chiamato main.py che conterrà il codice per creare il motore di renderizzazione del documento.
import jinja2
environment = jinja2.Environment()
template = environment.from_string("Hello, {{ name }}!")
print(template.render(name="World"))
Proviamo a lanciare il programma da shell con il comando
python main.py
E vediamo stampata a video la scritta Hello, World!, ecco che abbiamo appena generato il nostro primo documento da una stringa in parte statica e in parte dinamica.
Esempio di template da un file
Per questo esempio ci avvalleremo dell’uso dell’HTML per generare pagine web dinamiche. Riprendiamo il progetto appena creato e aggiungiamo una cartella chiamata templates e all’interno di essa un file chiamato index.html che sarà il modello da cui genereremo il documento. Ora scriviamo un po’ di codice. Modifichiamo il file main.py con il seguente listato.
from jinja2 import Environment, PackageLoader, select_autoescape, FileSystemLoader
import webview
* Salvo in una variabile la cartella dove risiedono i vari file 'templates'
* Che possono essere html, xml, csv, json, latex, txt, ecc...
file_loader = FileSystemLoader('templates')
* Creo l'ambiente dove vive jinja2
* Qui verranno gestite tutte le configurazioni
env = Environment(
loader=file_loader, * Carico il percorso dei file del template
autoescape=select_autoescape() * Utilizzo l'autoescape
)
* Recupero il template tramite il metogo get_template()
template = env.get_template("index.html")
* Con il metodo render() eseguo il rendering del template
print(template.render())
* Extra: tramite il package pywebview faccio un rendering dell'HTML che ho usato
* nell'esempio
titoloFinestra = "La mia finestra"
webview.create_window(titoloFinestra, html = template.render())
webview.start()
Dal listato precedente vediamo che dalla libreria di Jinja2 sono stati importati alcuni moduli tra cui Enviroment che una volta istanziato servirà a configurare l’ambiente dove vivrà il template. Altri moduli che abbiamo importato sono select_autoescape e FileSystemLoader. select_autoescape serve per abilitare l’escape automatico di Jinja, a volte quando si generano documenti HTML da modelli c’è il rischio che la renderizzazione di variabili vadano ad influire sull’HTML risultante. FileSystemLoader serve per indicare la cartella dove si trovano i template. Da notare che nel progetto per poter visualizzare il risultato in versione grafica ci siamo aiutati con la libreria pywebview che crea applicazioni desktop utilizzando codice html. Per poterla installare digitare il seguente comando.
pip install pywebview
Vediamo ora il codice del template, inseriamo all’interno di index.html il seguente listato.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</body>
</html>
Lanciamo il programma con il comando python main.py e vediamo il risultato finale.
Esempio template dinamico
Nel seguente esempio inseriremo nel template dei dati dinamici. modificare il file main.py come segue.
from jinja2 import Environment, PackageLoader, select_autoescape, FileSystemLoader
import webview
env = Environment(
loader = FileSystemLoader('templates'),
autoescape=select_autoescape()
)
* Recupero il template tramite il metodo get_template()
template = env.get_template("esempio_passaggio_di_variabili.html")
* Con il metodo render() eseguo il rendering del template
* Tra gli argomenti del metodo render posso passare dei dati da visualizzare nel 'templates'
* I dati possono essere di qualunque tipo variabili, liste, dizionari, oggetti, json
vista = template.render(
titolo = "Esempio passaggio di variabili",
sottoTitolo = "Per renderizzare le variabili bisogna inserire il segnaposto tra {{}}")
print(vista)
* Extra: tramite il package pywebview faccio un rendering dell'HTML che ho usato
* nell'esempio
titoloFinestra = "La mia finestra"
webview.create_window(titoloFinestra, html = vista)
webview.start()
Adesso modifichiamo il file index.html come segue.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>{{titolo}}</h1>
<h3>{{sottoTitolo}}</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>
</body>
</html>
Vediamo il risultato finale.
In questo tutorial abbiamo visto cos’è la libreria Jinja2, abbiamo visto anche come si usa tramite piccoli esempi, nei prossimi tutorial arricchiremo il nostro bagaglio vedendo altre funzionalità che rendono questo motore di template un valido strumento di sviluppo.
SviluppoMania
Stay Tuned