9.3. Créer un module Drupal personnalisé. Afficher une page de manière programmatique.
Commençons la création de notre module par un peu d’organisation. Continuons à séparer les modules personnalisés (custom) et ceux contribué (contrib). Dans Drupal, les modules se trouvent dans le dossier /modules
. Aujourd’hui, il n’est plus nécessaire de les placer profondément dans /sites/all/modules
, même si le readme indique que cela devrait fonctionner, utilisez plutôt le dossier /modules
. À l’intérieur de ce dossier, nous allons créer deux sous-dossiers : custom
et contrib
. Le dossier contrib
contiendra les modules supplémentaires provenant de drupal.org, et nos modules personnalisés seront dans le dossier custom
.
Sous-titres en anglais :
Les exemples de code sont disponibles sur GitHub :
https://github.com/levmyshkin/drupalbook8
Cette simple division des modules en dossiers contrib et custom semble superflue, mais croyez-moi, quand vous aurez 200 modules counter et 30 modules personnalisés sur votre site, vous comprendrez à quel point il est difficile de retrouver tous les modules custom et le code personnalisé. De plus, si vous modifiez du code dans un module tiers (ce qui ne doit être fait que si c’est absolument nécessaire), il est préférable de le déplacer dans le dossier custom pour éviter d’écraser ces modifications lors des mises à jour (ou qu’un autre développeur ou vous-même, sans le savoir, écrasiez ces modifications).
Créons donc notre module personnalisé. Créez le dossier /modules/custom/drupalbook
. Dans ce dossier, créez le fichier drupalbook.info.yml
:
name: DrupalBook
description: Custom module for learning Drupal 8
type: module
core: 8.x
core_version_requirement: ^8 || ^9
package: DrupalBook
Le fichier .info.yml
sert à décrire le module. Les informations indiquées seront affichées sur la page d’extension. Le nom du fichier est constitué du nom du module + .info.yml
.
Les fichiers YML de Drupal utilisent un format standard pour les configurations et réglages. Les champs et valeurs dans les fichiers YML sont séparés par un deux-points, chaque nouvelle ligne est indentée de deux espaces. La mise en forme est très importante : une erreur de format, un espace en trop ou un deux-points manquant, peut provoquer une erreur Drupal ou empêcher la lecture correcte du fichier.
Rendez-vous sur la page Extensions et activez votre module :
Maintenant que le module est activé, vous pouvez y ajouter des fonctionnalités qui fonctionneront sur votre site. Pour commencer, affichons un texte simple sur une page. Pour cela, il faut créer un autre fichier YML drupalbook.routing.yml
:
drupalbook.first_page:
path: '/first-page'
defaults:
_controller: '\Drupal\drupalbook\Controller\FirstPageController::content'
_title: 'Hello World!'
requirements:
_permission: 'access content'
Regardons plus en détail ce que contient ce fichier YML.
drupalbook.first_page : nom de notre route, c’est le chemin par lequel Drupal récupère la liste de toutes les routes et chemins. Ce nom doit être unique, il est conseillé d’utiliser module_nom.nom_route
car un module peut avoir plusieurs routes : drupalbook.first_page
, drupalbook.second_page
, etc.
path : '/first-page' — chemin vers la route. Faites attention à l’indentation de deux espaces, obligatoire. Si votre éditeur remplace le tab par des tabulations, changez-le pour utiliser deux espaces.
defaults : définit les paramètres par défaut de la route et la manière de la créer. Il existe plusieurs façons de créer une route, notamment via une classe Controller, mais aussi d’autres classes pour la création dynamique. Nous étudierons plus tard toutes les possibilités de routing, pour l’instant un exemple simple avec une classe Controller. Le routing Drupal utilise Symfony et ses bibliothèques. Symfony est un framework MVC utilisé aussi dans d’autres projets comme Laravel. MVC implique Model, View, Controller (ici, View n’est pas le module Views mais un template d’affichage, Model correspond aux classes entités pour la gestion de la base de données). Le Controller sert ici à la gestion des routes, ce que nous faisons dans cette leçon.
_controller : '\Drupal\drupalbook\Controller\FirstPageController::content' — indique quelle classe PHP affichera la page. Après les doubles deux-points, on précise la méthode à appeler pour afficher la page. La syntaxe avec beaucoup de barres sert à Drupal pour localiser la classe PHP dans le bon dossier.
_title : 'Hello World!' — le titre de la page.
_permission : 'access content' — permissions nécessaires pour accéder à cette page, l’utilisateur doit avoir un rôle avec ce droit.
Après avoir ajouté le fichier YML pour le routing, il faut créer la classe PHP qui affichera la page. Pour cela, il est important de comprendre l’autoloading des classes dans Drupal. Drupal charge uniquement les classes nécessaires pour afficher la page. Drupal utilise l’autoloading PSR-4 pour les classes PHP :
https://www.php-fig.org/psr/psr-4/
Regardons la ligne dans la route qui indique la classe PHP :
\Drupal\drupalbook\Controller\FirstPageController
\Drupal signifie que la classe est chargée via la bibliothèque Drupal, qui est désormais un package distinct accessible via packagist :
https://packagist.org/packages/drupal/drupal
Ensuite, on indique le nom du module :
\drupalbook
Puis on indique soit directement le nom de la classe dans le dossier du module, soit des sous-dossiers à l’intérieur du dossier src
, par exemple Controller
:
/modules/custom/drupalbook/src/Controller
Attention à la casse, PHP est sensible à la casse, donc controller
et Controller
sont différents.
Enfin, on ajoute le nom du fichier PHP :
/modules/custom/drupalbook/src/Controller/FirstPageController.php
Créons ce fichier :
/**
* @return
* Contains \Drupal\drupalbook\Controller\FirstPageController.
*/
namespace Drupal\drupalbook\Controller;
/**
* Fournit les réponses pour les routes du module DrupalBook.
*/
class FirstPageController {
/**
* Retourne une page simple.
*
* @return array
* Un tableau renderable simple.
*/
public function content() {
$element = array(
'#markup' => 'Hello World!',
);
return $element;
}
}
Voici la structure des fichiers attendue :
Il faut maintenant vider le cache pour que la nouvelle route soit prise en compte. La page sera accessible ici : http://drupalbook/first-page
Regardons maintenant la classe PHP qui affiche cette page.
/**
* @return
* Contains \Drupal\drupalbook\Controller\FirstPageController.
*/
Ici, on indique le chemin correspondant à la déclaration dans le fichier routing YML, ce qui indique à Drupal où trouver cette classe.
namespace Drupal\drupalbook\Controller;
Le namespace indique le chemin vers votre fichier classe. Faites attention, en copiant du code d’autres sites, à bien changer le nom du module pour le vôtre (ici drupalbook
).
class FirstPageController {
/**
* Retourne une page simple.
*
* @return array
* Un tableau renderable simple.
*/
public function content() {
$element = array(
'#markup' => 'Hello World!',
);
return $element;
}
}
Voici la classe qui affiche la page. Elle contient une méthode content()
que nous avons référencée dans le fichier drupalbook.routing.yml
. Cette méthode retourne un tableau avec un élément #markup
contenant le HTML à afficher. On retourne un tableau, pas une chaîne, car via une route, on peut aussi afficher un endpoint JSON pour une API, un fichier XML ou CSV.
Le code du module est disponible sur GitHub :
https://github.com/levmyshkin/drupalbook8
C’est tout, dans la prochaine leçon nous continuerons à enrichir notre module.