Dans le tutoriel précédent,
nous déclarions notre module Hello World auprès de Drupal 8. Nous allons maintenant créer une nouvelle page sur notre site Drupal, à l'adresse
<mon_site.com>/hello_world. Pour cela, nous devons créer une nouvelle route (via les nouveaux mécanismes Symphony 2 inclus dans Drupal 8). Une route est un concept Symphony associé au composant
routing (routage). Il permet de créer des "URL créatives", c'est à dire des URLs comme
/blog,
/mon-article ou encore
/hello_world et de leur associer un contrôleur qui va permettre de construire le contenu de cette page. Là encore nous verrons tout en détail dans un prochain article. Le but ici est de simplement présenter les principes de bases de la création de modules Drupal. Dans ce paragraphe nous allons voir les points suivants :
- nous devons créer des configurations via des fichiers YML dont les noms sont des conventions à retenir.
- nous devons utiliser des concepts de POO (Programmation Orientée Objet) et parfois étendre des classes de Drupal Core.
- nous devons utiliser un modèle MVC (Modèle / Vue / Controller) pour gérer nos pages (nous verrons ici le controller).
Création d'une nouvelle route
Commençons par créer notre nouvelle route. Celle-ci définiera une page dont l'URL sera /hello_world et appelant un controleur que nous définierons ensuite et dont le nom sera HelloWorldController. Symphony 2 permet de définir notre route de diverses manières : YML, XML ou PHP. La convention Drupal quant à elle, impose de créer la route dans un fichier $module.routing.yml et placé à la racine de l'arborescence de notre module (donc directement dans le dossier $module). Vous remarquerez l'usage de $module pour désigner le nom machine du module dans la documentation.
- De la même manière que pour le fichier .info.yml, créez un fichier hello_world.routing.yml :
-
Entrez le code suivant :
hello_world.hello_world:
path: '/hello_world'
defaults:
_controller: 'Drupal\hello_world\Controller\HelloWorldController::helloWorld'
_title: 'Hello World'
requirements:
_permission: 'access content'
- La première ligne définit la clef de la route. Nous verrons par la suite que nous pourrons créer des liens dans les menus de Drupal et que ces liens devront se référer à une route. C'est ce nom là qui définit notre route. Ici, j'ai choisi le nom hello_world.hello_world. Cela peut paraître bizarre, mais il faut retenir une chose : le nom de la route doit être unique. Autrement dit, il faut être sûr que ni Drupal, ni aucun autre module développé par n'importe quel développeur n'aura de route du même nom. Pour éviter un maximum les conflits, la convention est de choisir le nom de votre route comme ceci : nom_du_module.nom_de_la_page, où le nom_de_la_page représente ce que la page va faire. Par exemple, pour créer les formulaires d'enregistrement d'un nouvel utilisateur ou encore celui permettant à l'utilisateur de se loguer, le module user créera les routes : user.register et user.login dans son fichier user.routing.yml.
- La ligne path permet de définir l'URL de la page que nous souhaitons créer. Ici, /hello_world. Ce chemin doit commencer par un slash et ne pas dépasser neuf niveaux.
- La ligne defaults définit les données par défaut de cette route. Nous développerons les différentes possibilités dans un prochain article. Ici, nous avons utilisé les clefs suivantes :
- _controller : pour définir le contrôleur chargé de créer le contenu de cette page.
- _title : pour donner un titre à notre page.
D'autres données peuvent être utilisées. Par exemple la route user.login (définie par le module user) utilise la clef _form pour définir non pas une route se référent à une page avec un contenu, mais plutôt à un formulaire. Celui-ci s'affichera sur la page d'URL définie via la ligne path juste au dessus, mais pourra aussi être réutilisé par la suite dans un block.
- La ligne requirements définit les pré-requis que l'utilisateur de votre site doit avoir pour utiliser votre route. Dans notre cas, le pré-requis est d'avoir la permission
"access content" (définie par le module core node), c'est à dire le droit d'accès au contenu de notre site (qui pourrait être refusé aux utilisateurs non enregistrés). C'est le sens de la ligne dont la clef est _permission. Nous verrons la aussi dans un prochain article les différents pré-requis possibles, ainsi que comment créer nos propres permissions.

Nous venons de déclarer une nouvelle route pour créer une page dont l'URL est /hello_world et son contrôleur est HelloWorldControlleur. Pour l'instant, ce contrôleur n'existe pas. Si vous vous rendez sur la page /hello_world de votre site, vous n'aurez plus désormais une belle erreur "Cette page n'existe pas" car nous venons de la créer. A la place, vous aurez l'erreur suivante :
Création du contrôleur de la page
Durant la déclaration de la route précédente, nous avons délégué la création du contenu de la page à la méthode helloWorld du contrôleur HelloWorldController. C'est ce que nous retrouvions à la ligne :
_controller: 'Drupal\hello_world\Controller\HelloWorldController::helloWorld'
Les utilisateurs de Symphony reconnaîtront ici cette ligne mais noterons quelques différences : la
convention Symphony de nommage du contrôleur Bundle:Class:Method est quelque peu différente. Dans Drupal, la convention est la suivante : la clef utilisée sera la plupart du temps
_controller lorsque le contrôleur de la page renverra un contenu destiné à être rendu simplement dans un layout HTML. Nous verrons d'autres clefs dans un prochain article.
Le nom du contrôleur pointé par la clef _controller doit suivre la convention suivante :
_controller: \Drupal\nom_du_module\Controller\MaClasseController::maMethode
Notez que le chemin du contrôleur doit commencer par un slash. Notez également que le contrôleur sera placé dans un fichier nommé MaClasseController.php placée dans les répertoires src > Controller
eux-mêmes placés à la racine de votre module.
Le contrôleur est une classe de nom MaClasseController (remarquez que la première lettre de chaque mot est en majuscule, y compris la première et que le nom se termine par Controller). Enfin la fonction lancée par la route est la méthode maMethode présente dans la classe de mon contrôleur. On notera cette fois la présence d'une majuscule à chaque mot, sauf la première lettre.

Si vous avez bien suivi, un module nommé myModule est donc placé dans un dossier nommé également myModule dans le répertoire modules de l'installation Drupal. Un de ses contrôleurs appelé FooBarController sera dans un fichier php stocké ici (relativement à la racine de Drupal) :
modules/myModule/src/Controller/FooBarController.php
Cette convention de nommage du chemin est appelé PSR-4.
Bon, trêve de blabla, créons notre contrôleur ! Commençons par créer l'ensemble des sous-dossiers src/Controller dans notre module. Pour cela :
- Effectuez un clic-droit sur le projet de notre module, puis New -> Folder.
Ajouter de nouveaux dossiers dans notre module.
- Entrez le nom des différents fichiers de la structure à créer :
- Folder name : src/Controller
- Cliquez sur Finish.
Créer la hiérarchie des dossiers pour le contrôleur.
- Créez un fichier HelloWorldController.php. Normalement, vous devriez commencer à retenir comment faire !
- Effectuez un clic-droit sur le projet de votre module, puis New -> PHP File.
- Entrez le nom du fichier, File Name = HelloWorldController.php.
- Cliquez sur Finish.
Le fichier du nouveau contrôleur est désormais crée.
- Entrez désormais le code suivant :
<?php
/**
* @file
* Contains \Drupal\hello_world\Controller\HelloWorldController.
*/
namespace Drupal\hello_world\Controller;
use Drupal\Core\Controller\ControllerBase;
/**
* Controller routines for hello_world module routes.
*/
class HelloWorldController extends ControllerBase {
/**
* Return the 'Hello World' page.
*
* @return string
* A render array containing our 'Hello World' page content.
*/
public function helloWorld() {
$output = array();
$output['hello_world'] = array(
'#markup' => $this->t('Hello World!'),
);
return $output;
}
}
Le code ci-dessus est du PHP Objet relativement basique. Je vous ferais donc grâce de l'explication du fonctionnement des espaces de nommage et donc des lignes namespace et use. L'important dans ce code est de remarquer que nous définissons bien notre contrôleur : la classe HelloWorldController. Celle-ci implémente la classe abstraite ControllerBase. Cette interface définit un petit contrôleur basique ainsi que quelques méthodes utiles. Par exemple :
- l() : pour créer un lien vers une route existante.
- t() : pour traduire une chaîne de caractère dans la langue de l'utilisateur.
- currentUser() : pour récupérer un objet représentant l'utilisateur visitant la page.
- ...

Il est conseillé de réserver l'usage de ce contrôleur basique ControllerBase à des pages triviales, c'est à dire à des pages dont le contenu ne change pas selon l'utilisateur, par exemple un formulaire, la page de configuration de votre module, etc.. Les pages à la logique plus complexe où il sera intéressant d'adjoindre des tests unitaires préféreront l'interface : ContainerInjectionInterface.

Un peu de technique :
Bien que cela fonctionne techniquement, ce serait une erreur de ne pas hériter d'un contrôleur fourni par Drupal, comme par exemple ControllerBase. L'une des raisons est que l'usage de la fonction t() référencerait la fonction globale t() définie dans bootstrap.inc rendant difficile les unit tests de votre classe (à cause de dépendances globales). En utilisant $this->t(), nous faisons référence ici à l'implémentation de t() fournie par ControllerBase, elle-même basé sur l'usage d'un TranslationManager local.
Rappelez-vous la ligne suivante du fichier hello_world.routing.yml :
_controller: 'Drupal\hello_world\Controller\HelloWorldController::helloWorld'
Nous avons vu que cette ligne définit la cible de la route dans le contrôleur. En l’occurrence la méthode
helloWorld(). C'est cette méthode publique que l'on retrouve définie dans notre contrôleur. A l'intérieur de cette méthode, l'objet
$output est appelé "
Render Array" ou "
Renderable Array". Il s'agit d'une structure définissant un objet destiné à être rendu (affiché sur le site) en HTML. La clef
#markup définit le plus simple élément pouvant être affiché : une chaîne de caractères simple, rendue dans une
<div> ou un
<p>. Les propriétés à utiliser sont spécifiques à chaque type d'éléments pouvant être rendus (champ de texte, image, case à cocher, etc...) et chaque module peut ajouter éléments et propriétés. Créer une liste exhaustive est donc une tâche ardue voir impossible. A ma connaissance il n'y a pas de documentation complète des propriétés des
Render Array. Toutefois, il est à noter que les formulaires sont rendus (transformés en code HTML affichable) par le même mécanisme. Vous pouvez donc utiliser la documentation
Form API Reference pour trouver un maximum d'éléments et propriétés utiles. Enfin, vous pouvez lire la
documentation sur les Renderable Arrays qui définie un certain nombre de propriétés supplémentaires, notamment pour l'usage des caches, thèmes et autres.
- Activez à présent votre module (si ce n'est pas encore fait) ou videz le cache de votre site (si le module est déjà activé).
Rendez-vous à la page /hello_world de votre site ! Une (presque) magnifique page apparaît, avec votre titre et votre texte. C'est pas beau la vie ?!
Votre première page Hello World !
En résumé...
Basiquement, une route est un lien logique entre l'URL entrée dans le navigateur et la page (ou l'élément) devant s'afficher à l'écran. Cette route est définie dans un fichier $module.routing.yml placée à la racine du module.
Le Controller est la classe en charge de la création de l'élément en destination de route. Nous verrons plus tard pourquoi nous l'appelons Controller. Cette classe est placée dans un fichier nommé FooBarController.php, lui même inséré dans la structure de répertoire suivante :
/src/Controller.
Commentaires
Oui Dominique, c'est beau la
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
hello_world.info.yml
hello_world.routing.yml
lib/Drupal/hello_world/Controller/HelloWorldController.php
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Mise à jour
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Authorization:
Connection: keep-alive
Cookie: SESSb7ad567477c83756aab9a542b2be04f7=ptunobWKmH8HJw7hrOpArPMl-EZaCOWusUl54HQhFAc; SESS76c7c41d86289e5e99e0e28f24baa862=nHymq9STGhr4vUC1CkDg-xXglvu9uvfYmmD7i15vI1w; XDEBUG_SESSION=19152
Host: sandbox
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0
Re: Premier module Hello World : Créer une nouvelle page
Tout d'abords au niveau de l'endroit où créer le dossier Controller, dans la route tu dis qu'il faut le créer dans la racine du module mais lors de la création tu le crées dans le dossier /src (peut-être une modification faite durant la beta) et du coup que choisir ? racine ou /src, si on choisit le dossier src il faut modifier la route et les différents liens dans le Controller.php.
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
namespace Drupal\myModule\Controller
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page
Re: Premier module Hello World : Créer une nouvelle page