Templates Twig en PHP¶
L’installation de Twig se fait grâce à l’outil composer
composer¶
Si composer n’est pas présent dans votre environnement, il faut procéder à son installation.
Composer servira à beaucoup de tâches courantes dans un projet PHP.
On va d’abord créer un répertoire bin
à la racine de notre HOME
, placez-y l’exécutable composer.phar
et renommez le en composer
(ou faites un lien symbolique).
cd
mkdir bin
cd bin
curl -s https://getcomposer.org/installer | php
mv composer.phar composer
Si vous êtes derrière un proxy, vérifiez la définition de vos variables d’environnement http_proxy
et https_proxy
dans votre .bashrc
Ajoutez la ligne suivante à votre .bashrc
pour adapter votre PATH :
export PATH=$PATH:~/bin
de manière à ce que tous les programmes installés dans le répertoire bin de votre HOME soient accessibles de n’importe où.
Installation¶
Installons Twig:
composer require twig/twig
ou simplement :
composer require twig
Ceci créera dans le répertoire courant un dossier vendor contenant les librairies demandées et les dépendances.
On définit d’abord un template de base, BaseTemplate.html
:
<!DOCTYPE html>
<html lang="fr">
<head>
{% block head %}
<meta charset="utf-8">
<link rel="stylesheet" href="style.css" />
<title>{% block title %}{% endblock %}</title>
{% endblock %}
</head>
<body>
<section id="content">
{% block content %}{% endblock %}
</section>
<footer id="footer">
{% block footer %}
© Copyright 2023 <a href="http://monsite.com">
Mon super Site</a>.
{% endblock %}
</footer>
</body>
</html>
Puis un template plus spécialisé qui en hérite, menu.html
:
{% extends "BaseTemplate.html" %}
{% block title %}Menu de la semaine{% endblock %}
{% block head %}
{{ parent() }}
<style>
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Menu</h1>
<p class="important">
Voici votre menu de la semaine:
<dl>
<dt>Lundi</dt>
<dd>{{Lundi}}</dd>
<dt>Mardi</dt>
<dd>{{Mardi}}</dd>
<dt>Mercredi</dt>
<dd>{{Mercredi}}</dd>
<dt>Jeudi</dt>
<dd>{{Jeudi}}</dd>
</dl>
</p>
{% endblock %}
Enfin, on utilise ce template dans un fichier menu.php
en chargeant d’abord l”autoloader:
<?php
// menu.php
// inclure l'autoloader
include 'vendor/autoload.php';
try {
// le dossier ou on trouve les templates
$loader = new Twig\Loader\FilesystemLoader('templates');
// initialiser l'environement Twig
$twig = new Twig\Environment($loader);
// load template
$template = $twig->load('Menu.html');
// set template variables
// render template
echo $template->render(array(
'lundi' => 'Steak Frites',
'mardi' => 'Raviolis',
'mercredi' => 'Pot au Feu',
'jeudi' => 'Couscous',
'vendredi' => 'Poisson',
));
} catch (Exception $e) {
die ('ERROR: ' . $e->getMessage());
}
Affichage des personnes du Carnet¶
Affichons à présent les personnes du Carnet à l’aide d’un template Twig. On réutilise le fichier modele.php vu précédemment:
<?php
// modele.php
class Carnet {
private static $connexion;
function __construct(){
$dsn="mysql:dbname=".BASE.";host=".SERVER;
try{
self::$connexion=new PDO($dsn,USER,PASSWD);
}
catch(PDOException $e){
printf("Échec de la connexion : %s\n", $e->getMessage());
$this->connexion = NULL;
}
}
/** Récupére la liste des contacts sous forme d'un tableau */
function get_all_friends(){
$sql="SELECT * from CARNET";
$data=self::$connexion->query($sql);
return $data;
}
/** Ajoute un contact à la table CARNET */
function add_friend($data){
$sql = "INSERT INTO CARNET(NOM,PRENOM,NAISSANCE,VILLE) values (?,?,?,?)";
$stmt = self::$connexion->prepare($sql);
return $stmt->execute(array($data['nom'],
$data['prenom'], $data['naissance'],$data['ville']));
}
/** Récupére un contact à partir de son ID */
function get_friend_by_id($id)
{
$sql="SELECT * from CARNET where ID=:id";
$stmt=self::$connexion->prepare($sql);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_OBJ);
}
<?php
// fichier carnet.php
include 'vendor/autoload.php';
try {
// le dossier ou on trouve les templates
$loader = new Twig\Loader\FilesystemLoader('templates');
// initialiser l'environement Twig
$twig = new Twig\Environment($loader);
// load template
$template = $twig->load('carnet.html');
// on va instancier le modele
// et préparer les variables
// qu'on va passer au template
require_once("modele.php");
$contacts = new Contacts();
$amis = $contacts->get_all_friends();
$titre = "Liste des contacts";
// on passe ces données au template
// grace à la méthode render
echo $template->render(array(
'titre' => $titre,
'amis' => $amis,
));
} catch (Exception $e) {
die ('ERROR: ' . $e->getMessage());
}
et un template carnet.html :
{% extends "BaseTemplate.html" %}
{% block title %}Personnes du Carnet {% endblock %}
{% block head %}
{{ parent() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<p align="center" class="Style1">{{titre}}</p>
<table border="2" align="center" cellspacing="0" cellpadding="2" >
<tr bgcolor="#CA9999">
<td width="50"><strong>numero</strong></td>
<td width="50"><strong>Nom</strong></td>
<td width="50"><strong>Prenom</strong></td>
<td width="30"><strong>Age</strong></td>
<td width="50"><strong>Ville</strong></td>
</tr>
{% set i=0 %}
{% for ami in amis %}
{% set i=i+1 %}
{% if i is odd %}
<tr bgcolor="#F0F0F0">
{% else %}
<tr bgcolor="#A6A6A6">
{% endif %}
<td>{{ami.ID}}</td>
<td>{{ami.NOM}}</td>
<td>{{ami.PRENOM}}</td>
<td>{{ami.NAISSANCE}}</td>
<td>{{ami.VILLE}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Ce template est bien maladroit (car on peut faire plus simple, voir ci-dessous) mais il démontre l’expressivité du langage de template Twig avec des boucles, des conditionnelles, des déclarations et calculs avec des variables, etc.
Nous pouvons bien sûr en proposer un plus simple avec le CSS adéquat.
Affichage des Personnes avec un template plus simple¶
(carnet2.html)
{% extends "BaseTemplate.html" %}
{% block title %}Personnes du Carnet{% endblock %}
{% block head %}
{{ parent() }}
<link rel="stylesheet" href="static/css/tabstyle.css" />
{% endblock %}
{% block content %}
<h2>{{titre}}</h2>
<table id="jolie" class="centre" >
<tr>
<td>numero</td>
<td>Nom</td>
<td>Prenom</td>
<td>Age</td>
<td>Ville</td>
</tr>
{% for ami in amis %}
<tr>
<td>{{ami.ID}}</td>
<td>{{ami.NOM}}</td>
<td>{{ami.PRENOM}}</td>
<td>{{ami.NAISSANCE}}</td>
<td>{{ami.VILLE}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
avec le style CSS qui va bien sur les tableaux …
Nous pouvons ainsi compléter le développement MVC effectué précédemment en utilisant des templates Twig. Voir sur github/roza/php-basic-mvc pour un code plus complet. Mais le système de routage employé est encore très rudimentaire.
Nous pouvons ensuite utliser des outils de microframeworks Web comme Phalcon ou Slim ou directement ceux du Framework de référence : Symfony pour aller plus loin.