Créer son application Web en PHP (et Composer) : Partie 3
Vous avez maintenant une architecture métier prête à l'emploi. Maintenant, la question est de savoir comment s'en servir pour afficher du contenu à vos utilisateurs. C'est précisément le sujet de cette 3e partie !
Publié le lun. 01 avr (21:17). Actualisé le mar. 31 déc (16:24)
.jpg)
Nous voilà arrivés à la 3e partie de ce tutoriel, qui consiste en l'affichage de contenu à vos utilisateurs avec votre architecture. On pourrait très bien faire un simple require
d'une page en PHP à la fin de notre Controller
, et se servir d'une variable qui contient toutes les infos requises. Toutefois, je n'aurais pas consacré une partie entière à cela. On va donc reprendre ce principe, avec l'aide d'un moteur de Template. Et pour cela, prenons le mastodonte en la matière : Twig !
Vous en avez certainement entendu parlé, il est notamment intégré dans le framework Symfony. Le but de Twig va être de simplifier notre tâche lorsqu'on doit afficher des informations spécifiques côté client, mais de manière plus lisible et plus simplifiée qu'en PHP standard. Par exemple, pour afficher le nom d'un utilisateur s'il est connecté, on aurait dû procédé de cette manière en PHP :
<?php
if (isset($_SESSION['user_session'])) {
echo $user['name'];
}
?>
Alors qu'avec Twig, cela donne le code suivant :
{% if session is defined %} {{ user['name'] }} {% endif %}
Beaucoup plus de concision. Vous l'avez remarqué, il y a moins de ponctuation, et vous n'avez plus à vous embêter avec autant de parenthèses. Cela vous sauve des heures de débogage pour savoir quelle parenthèse n'est pas fermée. Notez bien que les variables employés dans le code au-dessus ont été définies en amont, mais nous verrons cela plus tard.
I/ La configuration côté serveur
Sans plus attendre, intégrons Twig à notre projet ! Bien sûr, j'utilise Twig dans l'exemple, mais libre à vous de choisir un autre moteur de Template.
composer require twig/twig
La première chose à faire va être de gérer le chargement de Twig au sein de notre injecteur de dépendances. On va donc faire appel à une fonction un peu spéciale d'Auryn : delegate()
. Cette méthode va déléguer le chargement de la classe à une fonction anonyme, laquelle contiendra la configuration de Twig. Ajoutez alors ce bout de code dans votre fichier Dependencies.php
:
$injector->delegate('Twig_Environment', function () use ($injector) {
$loader = new Twig_Loader_Filesystem(dirname(__DIR__) . '/templates');
$twig = new Twig_Environment($loader, ['debug' => true]);
$twig->addExtension(new \Twig\Extension\DebugExtension());
return $twig;
});
$injector->alias('Project\Templates\Renderer', 'Project\Templates\TwigRenderer');
$injector->alias('Project\Templates\FrontendRenderer', 'Project\Templates\FrontendTwigRenderer');
On n'oublie pas le petit alias pour simplifier l'injection du Renderer de Twig ! Maintenant dirigez-vous dans votre dossier Templates/
(localisé dans votre projet src/
, comme indiqué dans la 1ère partie), pour y insérer 4 nouveaux fichiers, qui vont donc générer votre template front-end :
FrontendRenderer.php
<?php
// ./src/Templates/FrontendRenderer.php
namespace Project\Templates;
interface FrontendRenderer extends Renderer {}
FrontendTwigRenderer.php
<?php
// ./src/Templates/FrontendTwigRenderer.php
namespace Project\Templates;
class FrontendTwigRenderer implements FrontendRenderer
{
private $renderer;
public function __construct(Renderer $renderer)
{
$this->renderer = $renderer;
}
public function render($template, $data = []) : string
{
return $this->renderer->render($template, $data);
}
}
Renderer.php
<?php
namespace Project\Templates;
interface Renderer
{
public function render($template, $data = []) : string;
}
TwigRenderer.php
<?php
namespace Project\Template;
use Twig_Environment;
class TwigRenderer implements Renderer
{
private $renderer;
public function __construct(Twig_Environment $renderer)
{
$this->renderer = $renderer;
}
public function render($template, $data = []) : string
{
return $this->renderer->render("$template.html", $data);
}
}
Une fois créés, rendez-vous dans le Controller
que nous avons ajouté lors de la partie précédente. Nous allons y intégrer notre générateur de Template. Grâce à notre injecteur de dépendances, nous n'aurons besoin que d'une ligne, à ajouter au début du fichier, après la déclaration du namespace :
use Project\Template\FrontendRenderer;
Pour mémoire, FrontendRenderer
se réfère à FrontendTwigRenderer
, dont nous avons défini l'alias plus tôt dans notre fichier Dependencies.php
. Maintenant, il faut faire appel à la fonction render()
définie dans notre fichier FrontendTwigRenderer.php
. Mais avant cela, il nous faut définir une variable avec les informations à afficher sur la page. Votre classe Index devrait ressembler à ceci :
<?php
// src/Controllers/Index.php
namespace Project\Controllers;
use Sabre\HTTP\Sapi;
use Sabre\HTTP\Response;
use Project\Templates\FrontendRenderer;
class IndexView
{
private $_response;
private $_request;
private $_renderer;
public function __construct(
Sapi $request,
Response $response,
FrontendRenderer $renderer
) {
$this->_request = $request;
$this->_response = $response;
$this->_renderer = $renderer;
}
public function show()
{
// ... Récupérer les articles déjà présents via une requête en DB, ou sur un fichier, peu importe au final.
// Remarque : si vous utilisez une autre classe pour aller chercher vos données :
// Pensez à toujours spécifier un namespace, pour que vous alliez chercher la bonne classe lors de l'intégration.
$data = [
'title' => 'Index'
];
$html = $this->_renderer->render('Index', $data);
$this->_response->setBody($html);
}
}
Vous aurez remarqué qu'on a ajouté notre renderer
parmi les attributs de la classe, toujours dans le cadre de l'inversion de contrôle réalisée dans la partie précédente. Dans notre fonction show()
, il suffit simplement de créer une variable qui contiendra toutes les informations à ajouter. Ensuite, créez une autre variable qui contiendra le résultat de la génération du Template, en passant en premier paramètre le nom du fichier (sans l'extension), avec les informations à passer comme second paramètre.
Enfin, rien de plus sorcier, vous n'avez qu'à passer le résultat de la génération du template dans votre objet Response
, et le tour est joué ! Passons maintenant à un petit guide d'utilisation de Twig côté front-end !
II/ L'utilisation de Twig côté client
Consacrons maintenant une partie, certes un peu plus courte, sur l'utilisation de Twig côté client. Évidemment, je reprendrai les points clefs qui nous intéressent, mais vous pouvez très bien aller consulter la doc de Twig sur leur site. Tout d'abord, vous devez savoir que Twig utilise des accolades pour les instructions. Vous l'avez vu précédemment, 2 paires d'accolades servent à afficher des données :
{{ data['title'] }}
Toutefois, Twig ne se résume pas qu'à cela ! Vous pouvez implémenter de la logique dans votre template, comme des conditions ou des boucles.
A. Les conditions
S'agissant des conditions, la syntaxe est la suivante :
{% if session is defined %} {{ user['name'] }} {% endif %}
Plusieurs remarques sur ce bout de code :
- Les instructions de logique dans Twig se démarquent comme ceci :
{% instructions %}
- Lorsque vous commencez une condition (cela vaut pour les boucles), vous devez indiquer la fin de l'instruction par
{% endif %}
, et{% endfor %}
pour une boucle - Vous pouvez très bien imbriquer des conditions, par exemple :
{% if session is defined %}
{% if user['id'] == 1 %}
{{ user['name'] }}
{% endif %}
{% else %}
Connectez-vous
{% endif %}
Dans cet exemple, j'ai imbriqué plusieurs conditions, et j'ai également rajouté une condition else
pour la première condition. Vous l'avez remarqué, cela ressemble beaucoup au PHP normal. Toutefois, vous gagnez en simplicité et en lisibilité ; ce sera beaucoup plus simple de réviser votre code.
B. Les boucles
S'agissant des boucles, rien de bien sorcier non plus. La particularité est que vous pouvez ajouter des filtres d'une manière beaucoup plus simple qu'en PHP :
{% for key, item in items|slice(0, 5) %}
{{ item }}
{% endfor %}
Ici, la boucle n'itèrera à travers que les 5 premières entrée du tableau items. De plus, le mot-clé key
indique que nous souhaitons également afficher la clé de l'entrée de l'itération en cours.
Encore une fois, vous avez remarqué la présence de l'instruction {% endfor %}
, qui permet de clore la boucle. Si Twig ne détecte pas de tel mot-clé avant la fin du code, que ce soit pour une condition ou une boucle, vous aurez une petite erreur à l'arrivée !
C. Les blocs
En tant que moteur de Template, Twig fonctionne par blocs. C'est l'équivalent des buffers en PHP, avec ob_start()
et ob_get_clean()
. Avec Twig, un bloc ressemble à ceci :
{% extends "Layout.html" %}
{% block content %}
// Un peu de HTML...
{% endblock content %}
Un bloc se déclare donc de la même façon qu'un boucle ou une condition. Notez également la présence du nom du bloc, qui sera très important lorsque si vous importez votre template.
En parlant de cela, vous avez remarqué le première ligne, qui contient "{% extends "Layout.html" %}
" : cela permet à Twig d'intégrer votre template de base (avec un en-tête, un pied-de-page, par exemple), et d'intégrer votre bloc de contenu là où vous l'avez choisi. Pour ce faire, rien de plus simple, faites comme si vous alliez créer un bloc, mais ne mettez rien entre les balises, et mettez le même nom de bloc :
{% block content %} {% endblock content %}
De cette manière, le contenu du bloc que vous avez défini ailleurs se retrouvera à l'endroit prévu !
On en arrive à la fin de cette 3e partie. Il y aura une dernière partie consacrée à la mise en application pratique de ce que nous avons appris, afin que vous puissiez vous faire une idée de l'agencement de toutes ces dépendances en pratique. D'ici-là portez-vous bien et à bientôt pour une prochaine publication !
Ces publications pourraient vous intéresser...
.jpg)
Créer son application Web en PHP (et Composer) : Partie 2
Notre projet dispose maintenant des fonctionnalités premières d'un site. Maintenant, le problème est de savoir comment simplifier et automatiser au maximum l'exécution de notre code lors d'une requête utilisateur.
lun. 25 mar (20:31)
10

Créer son application Web en PHP (et Composer) : Partie 1
Vous avez un projet de grande envergure mais ne voulez pas vous embêter avec ces frameworks PHP pré-conçus ? Vous êtes au bon endroit !
mar. 19 mar (17:53)
7
Commentaires
Vous pouvez publier un commentaire pour donner votre avis sur la publication, ou poser vos questions le cas échéant. Veillez à rester courtois et respectueux vis-à-vis des autres membres. En cas de détection d'un commentaire allant à l'encontre des règles du site, le commentaire sera supprimé.
Vous devez être connecté pour publier un commentaire. Connectez-vous.
Signaler un commentaire