Langages de templates Twig et ses compagnons

Séparation des vues

Le problème : considérez ce gestionnaire (PHP)

$res = '<html><head><title>Bla</title><body><table>';
foreach ($array as $k => $v) {
	$res .= "<tr><td>$k</td><td>$v</td></tr>";
}
return $res . '</table></body></html>';
  • Confusion entre logique et présentation,
  • Code difficile à lire et à organiser,
  • Syntaxe très lourde (répétition de la variable $res),
  • Pas possible de colorier la syntaxe HTML dans un éditeur,
  • Risques de sécurité…

Les templates naissent pour résoudre ces problèmes.

Templates

Un exemple de template (Twig)

<!DOCTYPE html>
<html>
  <head>
    <title>Blabla</title>
  </head>
  <body>
    <h1>Bonjour {{ user }}</h1>
	
	{% include 'content.html' %}
  </body>
</html>
  • La valeur de la variable user est remplacée pour {{ user }} ;
  • Le contenu de content.html est inséré dans la sortie ;
  • Tout le reste est renvoyé à l’identique.

Langages de templating

Les langanges de templating permettent, en général, de

  • Remplacer des variables ({{ var }}) ;
  • Exécuter des tests ({% if %}) ;
  • Boucler sur des tableaux ({% for %}) ;
  • Inclure d’autres templates ({% include %}, {% block %}, {% extends %}) ;
  • Chaîner des transformations ({{ var | upper | strip }}) ;
  • Appliquer des opérateurs simples (mathématiques, logiques, comparaisons).

Quelques langages de templating

Twig (langage de templates par défaut de Silex)

Contexte : dictionnaire d’associations clé → valeur passé au template. Par exemple :

  • nomtoto
  • users[titi, tutu, tata]

Substitution de variables, filtres

Hello {{ nom }}
Hello toto

Filtres

En majuscules : {{ nom | upper }}
Une liste : {{ users | join(', ') }}

{% filter upper %}
  {{ nom }}
{% endfilter %}
En majuscules : TOTO
Une liste : titi, tutu, tata


  TOTO

Contrôle

Conditionnel

{% if nom == 'toto' %}
Bonjour mon cher
{% else %}
Bonjour
{% endif %}
Bonjour mon cher

Boucle

{% for i in range(0, 3) %}
  Utilisateur : {{ users[i] }}
{% endfor %}

{% for u in users %}
  Utilisateur : {{ u }}
{% endfor %}
Utilisateur: titi
Utilisateur: tutu
Utilisateur: tata

Utilisateur: titi
Utilisateur: tutu
Utilisateur: tata

Modularité

Inclusion

{% include 'autre_template.html' %}

Macros

{% macro greet(nom) %}
  Bonjour Mr {{ nom }}
{% endmacro %}
{% from "macros.html" import greet %}

{{ greet('toto') }}
Bonjour Mr toto

Héritage

Voici le template `main.html`
Les blocs sont affichés tels quels

{% block titre %}
  Un titre quelconque
{% endblock %}

{% block pied %}
  Copyright Pinco Pallino
{% endblock %}
Voici le template `main.html`
Les blocs sont affichés tels quels

  Un titre quelconque

  Copyright Pinco Pallino
{% extends 'main.html' %}

{% block titre %}
  Remplace titre
{% endblock %}
Voici le template `main.html`
Les blocs sont affichés tels quels

  Remplace titre

  Copyright Pinco Pallino

Utiliser Twig: render

dans Silex

$app->register(new Silex\Provider\TwigServiceProvider(), 
               array('twig.path' => 'templates'));

$app->get('/', function(Application $app) {
	return $app['twig']->render('hello.html', array(
		'nom' => 'Toto'
	));
});

dans Express (s’applique aussi à d’autres langages de templating)

var twig = require('twig');
app.set('views', 'templates');       // où trouver les templates
app.set('view engine', 'html');      // à quelle extension
app.engine('html', twig.__express);  // associer twig
app.set('twig options', {
    autoescape: true                 // échappement automatique
});

app.get('/', function(req, res) {
	res.render('hello.html', { 'nom' : 'Toto' });
});

Échappement

  • La programmation web comporte le melange de plusieurs langages de programmation : HTML, CSS, JavaScript, PHP, templates, SQL, …
  • Chaque langage a ses caractères spéciaux. Par ex.: <, >, &, ', "

Considérez ce gestionnaire

function(Request $req) {
  return '<h1>' . $req->query->get('nom') . '</h1>';
}

Nom :

Les caractères <U , Z> sont interprétés comme la balise <U>.

Échappement HTML

HTML définit des séquences d’échappement pour ses caractères spéciaux, appelées character entities.

&lt; &gt; &amp; &quot; &apos;
< > & " '

Ces remplacements sont appliqués automatiquement par

  • La fonction htmlspecialchars() de PHP,
  • La fonction $app->escape() de Silex,
  • Twig et la majorité des autres moteurs de templates,
  • Des modules de Node.js, comme escape-html.

ATTENTION : n’utiliser que pour du HTML !

  • JSON : remplacer '\', "\",
  • JavaScript : comme JSON, mais avec beaucoup de soin !

Échappement dans Twig

Les remplacements {{ var }} sont échappés par défaut.

Désactiver l’échappement :

{% autoescape false %} {{ nom }} {% endautoescape %}
{{ nom | raw }}

Réactiver l’échappement :

{% autoescape 'html' %}{{ nom }}{% endautoescape %}
{% autoescape 'css' %}{{ nom }}{% endautoescape %}
{{ nom | escape }}
{{ nom | e }}

Nom :

Lectures

Fork me on GitHub