Twig è un template engine scritto in PHP da SensioLabs, la stessa compagnia che ha sviluppato anche Symfony. I suoi punti di forza principali sono:
- Velocità: converte i template in codice PHP ottimizzato riducendo l'overhead al minimo.
- Sicurezza: utilizza una sandbox per verificare il codice.
- Flessibilità: consente allo sviluppatore di estendere tag e filtri in maniera semplice.
Abbiamo visto nella precedente lezione come un controller comunica con la vista e come, quindi, utilizzare Twig per stampare a schermo il contenuto delle variabili. In questa lezione descriveremo, invece, come sfruttare appieno questo linguaggio di templating.
In effetti Symfony non obbliga ad utilizzare Twig come template engine, si ha la possibilità di lasciare questo compito al PHP puro ma personalmente sconsiglio questa tecnica. Separare la logica dalla presentazione è un requisito fondamentale.
Prendendo l'esempio presente nella documentazione ufficiale, analizziamo alcuni costrutti importanti del linguaggio:
<!DOCTYPE html>
<html>
<head>
<title>My Webpage</title>
</head>
<body>
<ul id="navigation">
{% for item in navigation %}
<li><a href="{{ item.href }}">{{ item.caption }}</a></li>
{% endfor %}
</ul>
<h1>My Webpage</h1>
{{ a_variable }}
</body>
</html>
Notiamo da subito che esistono sono due tipi differenti di costrutti:
- "costrutti delimitati da
{{ ... }}
": utilizzati principalmente per stampare qualcosa a schermo, ad esempio una variabile o il risultato di una funzione o un'espressione. - "costrutti delimitati da
{% ... %}
": utilizzati per eseguire istruzioni, ad esempio un ciclo o l'assegnamento di un valore ad una variabile. I comandi contenuti all'interno di questo costrutto sono chiamatitag
.
Tutto quello che scriveremo con Twig, commenti a parte che sono delimitati da {# #}
, saranno racchiusi in queste due tipologie di sintassi.
Utilizzo delle variabili
Per utilizzare le variabili basta includerle all'interno di {{ ... }}
e verranno stampate a schermo. Per accedere ad un elemento di un array o di un oggetto possiamo usare una delle due notazioni, entrambe valide:
user.name
user['name']
Ci sono inoltre alcune variabili sempre presenti all'interno di ogni template:
Variabile | Descrizione |
---|---|
_self |
Riferimento al template corrente |
_context |
Riferimento al contesto corrente |
_charset |
Riferimento al charset corrente |
oppure, nel nostro caso in cui si utilizzi Symfony:
Variabile | Descrizione |
---|---|
app |
Fornisce accesso ad alcuni oggetti di uso comune. Ad esempio all'oggetto user , all'oggeto request , security etc. |
L'assegnazione di un valore ad una variabile può essere effettuata attraverso il tag set
:
{% set href = "http://www.google.com" %}
{% set odds = [ 1, 3, 5, 7 ] %}
{% set profile = { 'name': 'Simone', 'lastname': 'Rossi' }
{% set content}<h1>This is html content</h1>{% endset %}
Una volta definita, la variabile può essere utilizzata nella modalità classica.
Utilizzo dei filtri
I filtri sono funzioni che modificano il valore di una variabile. Si pensi ad esempio a tutte quelle funzioni PHP che trasformano il valore di una stringa: strtoupper
, strtolower
, ... In Twig sono utilizzate attraverso la pipe |
e vengono accettati alcuni argomenti:
{{ href|lower }}
{{ odds|join(',') }}
Il primo esempio converte il valore della stringa in lowercase, il secondo invece stampa il contenuto dell'array odds
separando gli elemento con una virgola. È possibile consultare la lista dei filtri nella documentazione ufficiale.
Utilizzo delle Funzioni
Alcune funzioni messe a disposizione da Twig sono:
Funzione | Descrizione |
---|---|
dump |
Esegue un var_dump della variabile |
max e min |
Restituiscono il massimo e il minimo di una lista |
random |
Restituisce un valore random oppure un elemento random da una lista se passata come parametro |
Anche la lista delle funzioni è disponibile nella documentazione ufficiale.
Le strutture di controllo
I cicli e i controlli condizionali sono contenuti all'interno di blocchi {% ... %}.
{% if value >= 1 %}
<h1>Single value
{% else %}
<h1>Multiple value</h1>
{% endif %}
{% if users %}
<ul>
{% for user in users %}
<li>{{ user.name }}</li>
{% endfor %}
</ul>
{% endif %}
Alcuni utilizzi del ciclo for
avanzati:
{# ciclo da 0 a 10 #}
{% for i in 0..10 %}
* {{ i }}
{% endfor %}
{# ciclo da 'a' a 'z' #}
{% for letter in 'a'..'z' %}
* {{ letter }}
{% endfor %}
All'interno del ciclo for
, inoltre, è disponibile la variabile loop
:
Elemento | Descrizione |
---|---|
loop.index |
L'indice corrente (1 indexed) |
loop.index0 |
L'indice corrente (0 indexed) |
loop.revindex |
L'indice corrente dalla fine del loop (1 indexed) |
loop.revindex0 |
L'indice corrente dalla fine del loop (0 indexed) |
loop.first |
Vero se è il primo elemento del ciclo |
loop.last |
Vero se è l'ultimo elemento dell'iterazione |
loop.length |
Numero di elementi |
loop.parent |
Il parent context |
Il ciclo for
che abbiamo visto in precedenza con l'if
che controlla gli utenti, può essere scritto anche in questo modo:
<ul>
{% for user in users %}
<li>{{ user.name }}</li>
{% else %}
<li><em>no user found</em></li>
{% endfor %}
</ul>
Ereditarietà dei template
Una caratteristica molto importante di Twig è la template inheritance che consente di suddividere la struttura della pagina in "blocchi" che possono essere poi sovrascritti in base alle esigenze. Vedremo più avanti come sfruttare in pieno questa caratteristica. Per ora è sufficiente sapere che ciò viene realizzato attraverso il tag block
:
{% block content %}
<h1>Title</h1>
<p>Lorem ipsum dolor sit amet</p>
{% endblock %}
Terminato per ora il discorso relativo al template engine Twig in Symfony2, l'argomento della prossima lezione saranno l'interazione con i database e l'utilizzo di un ORM come Doctrine.