Initiation au développement de module custom sur Drupal 10
- Blog
- CMS
- Initiation au développement de module custom sur Drupal 8
Avec l’ajout de Symfony, Drupal 8 a introduit un changement important dans le développement des modules custom.
Sur Drupal 8, le dossier modules se trouve à la racine de votre installation Drupal et non dans le dossier /sites/all/modules comme c’était le cas sur Drupal 7.
Dans un premier temps, nous allons créer un répertoire “custom” dans le dossier “modules”. Ce dernier rassemblera l’ensemble de vos modules custom. Ensuite nous allons créer un deuxième répertoire dans le dossier custom. Le nom de ce dossier est le nom dit “machine” de votre module custom. Il doit être unique, en minuscule et sans espace.
Le chemin de votre module custom doit être /modules/custom/mon_module.
Dans un premier temps, nous allons créer un répertoire “custom” dans le dossier “modules”. Ce dernier rassemblera l’ensemble de vos modules custom. Ensuite nous allons créer un deuxième répertoire dans le dossier custom. Le nom de ce dossier est le nom dit “machine” de votre module custom. Il doit être unique, en minuscule et sans espace.
Le chemin de votre module custom doit être /modules/custom/mon_module.
Si votre module custom a vocation à être publié sur drupal.org (et ainsi éviter les soucis de concordance entre deux modules de même nom), vous pouvez vérifier que le nom choisi n’existe pas en vérifiant que la page https://www.drupal.org/project/mon_module n’existe pas.
Par la suite nous verrons comment :
- Créer une route avec le système de routing proposé par Symfony
- Créer une page avec un contrôleur
- Créer un lien de menu vers notre page
- Créer et instanciation un service
- Utiliser l’injection de dépendance
- Créer un bloc via un plugin
- Stocker et récupérer des variables via Drupal Config
- Créer un formulaire accessible depuis le back-office
Vous souhaitez en savoir plus ?
Prenez un rendez-vous de 15 minutes pour discuter :
Elsa Bestault
Head of Digital Consulting
1. Création du module custom
La première étape pour la création d’un module custom sous Drupal 8 est la création d’un fichier “mon_module.info.yml”. Autrement appelé mon_module.info sous Drupal 7. En effet, Drupal 8 utilise le format YAML.
Dans notre fichier .info.yml, nous allons insérer le code suivant :
La propriété name définit le nom du module, core la version de Drupal nécessaire au bon fonctionnement et type indique que nous sommes en train de créer un module.
La propriété description permet d’ajouter une description à votre module et la propriété package permet de regrouper votre module sous le nom “Mes modules”.
A ce stade, votre module ne fait rien mais s’affiche désormais dans la liste des modules.
Il est également possible de créer un fichier mon_module.module afin d’utiliser les différents hooks disponible sur drupal 8.
En résumé votre module custom :
- Doit avoir un nom “machine” unique, en minuscule et sans espace.
- Doit être créé dans le répertoire modules/custom.
- Doit contenir au minimum le fichier .info.yml décrivant le titre du module, la version du core de Drupal 8 et le type.
2. Création d’une route
Une route est une notion de Symfony associée au système de routing. Cela permet de créer des URLs comme /mon-module, /ma-page, /bonjour,... et de leur associer un contrôleur Symfony qui va nous permettre de bâtir le contenu de la page.
Plus d’informations sur le routing dans la documentation officielle de Symfony.
Nous allons maintenant créer le fichier « mon_module.routing.yml » avec le code suivant :
- La première ligne indique la clé unique de la route.
- La propriété “path” définit l’url de la page que nous allons créer.
- La propriété “défauts” définit les données par défaut de notre route. Dans notre exemple, nous ajoutons l’appel à un contrôleur.
- La propriété “requirements” définit les règles obligatoires d’accès pour pouvoir utiliser notre route.
Pour l’instant, le contrôleur “MaPageController” n’existe pas. Si nous tentons d’accéder à l’url /ma-page, une erreur s’affiche.
3. Création d’un contrôleur
Lors de la création de notre route, nous avons mandaté la création du contenu de notre page à la méthode maPage du contrôleur MaPageController. Ceci est définie via la ligne ci-dessous.
Nous allons maintenant créer un fichier MaPageController.php et le placer dans le répertoire suivant : modules/custom/mon_module/src/Controller/MaPageController.php
Dans notre cas, le contrôleur est une classe du nom MaPageController (attention à bien respecter la nomenclature du “camel case” . Cela signifie que la première lettre de chaque mot doit être en majuscule. Le nom du controller doit également se terminer par Controller. Exemple : MaPageController)
Après avoir créé notre nouveau fichier, entrez le code suivant :
Nous remarquons dans ce code, que nous définissons bien notre contrôleur avec la classe MaPageController qui implémente la classe ControllerBase.
Avec le ControllerBase, il est possible d’utiliser la fonction de traduction t()
Une fois sauvegardé, rendez-vous sur la page /ma-page.
4. Création d’un lien
Sous Drupal 7, la création d’un lien de menu custom se faisait via un hook_menu(). Sous Drupal 8, la création d’un lien de menu est désormais possible via une configuration YAML.
Comme pour les étapes précédentes, nous allons créer un fichier nommé “mon_module.links.menu.yml”.
Insérez le code suivant :
Dans ce fichier, vous pouvez définir l’ensemble des liens de menu de votre module custom. Il suffit de les définir les uns en dessous des autres.
- La première ligne indique la clé unique pour le lien.
- La propriété “title” définit le titre du lien (requis.
- La propriété “description” permet d’ajouter une description au menu (optionnel.
- La propriété “route_name” indique la route à appeler lors du clic sur le lien.
- Il est possible d’y ajouter plusieurs propriétés optionnelles (parent, weight,...)
Afin d’activer notre lien de menu, pensez à vider les caches. Action possible via drush ou via le back-office de drupal (/admin/config/development/performance.
5. Création d'un service
Un service est une classe qui propose des fonctionnalités spécifiques et globales à l’ensemble du projet. La méthode d'instanciation d’un service se fait via un Service Container. Celui-ci s’occupe de la création et de l'initialisation de l'objet.
Sous Drupal 7, pour appeler une fonction d’un autre module, nous aurions utilisé la fonction module_invoke. Avec Drupal 8 et l’adoption du concept de Service Container basée sur le Symfony, il suffit d’utiliser l’injection de dépendance afin que l’utilisation soit transparente pour l’utilisateur du service.
Nous allons maintenant déclarer un service dans notre module “mon_module”. Pour cela, il faut créer un fichier mon_module.services.yml avec le code suivant :
Ensuite, nous allons déclarer notre classe “Date” dans le répertoire suivant : modules/custom/mon_module/src/Service/Date.php
Dans notre exemple, nous venons d’ajouter une fonction permettant de récupérer le nombre de jours entre deux dates
Pour utiliser un service dans un module, il suffit de l’appeler en utilisant le Service Container de Drupal
Le Service Container va alors instancier l’objet, l’initialiser et le renvoyer. Maintenant, il suffit de l’utiliser pour appeler la fonction differenceDate()
En résumé et de la même façon, il est possible d’appeler un service du core de Drupal
6. Injection de dépendance
Afin d’éviter la répétition de l’appel au Service Container de Drupal, il suffit d’étendre la classe ControllerBase pour ainsi retrouver les services dans la méthode “create” du contrôleur. Ci-dessous un exemple de contrôleur avec une injection de dépendance du service Date précédemment créé.
7. Création d’un plugin
Sous Drupal 8, un plugin a pour vocation de remplacer les différents hook_xxx_info() de Drupal 7 et de leurs hook respectifs (block, form, view,...) sous une approche orientée objet.
Nous allons créer un block en utilisant le système de plugin fourni par Drupal 8.
Commençons par créer un fichier MonBlock.php dans le répertoire : /modules/custom/mon_module/src/Plugin/Block
Dans ce fichier, nous allons créer une classe qui étends la classe BlockBase de Drupal 8.
Dans ce code, plusieurs fonctions :
- build() : Permet de gérer le contenu afficher dans le bloc. Ici nous affichons la phrase “Voici ma date de naissance : 2020-26-04” .
- blockForm() : Permet d’ajouter un formulaire lors de modification du bloc depuis le back-office.
- blockSubmit() : Permet d’exécuter du code lorsqu’on clique sur le bouton enregistrer lors de la modification du bloc depuis le back-office.
Il est important de noter et de respecter le commentaire au-dessus de la déclaration de la classe :
id : Identifiant unique du bloc admin_label : Nom du bloc depuis le back-office category : Catégorie du bloc. Permet de regrouper plusieurs blocs sous la même catégorie.
Afin d’activer le nouveau bloc, pensez à vider les caches. Action possible via drush ou via le back-office de drupal (/admin/config/development/performance).
Notre nouveau bloc apparaît dans la liste des blocs depuis le back-office.
8. Variables de configuration du module custom
Depuis Drupal 8, il est possible d’ajouter des variables de configuration qui s’initialise lors de l’activation du module. Une fois activé, ces variables peuvent être récupérer et modifier.
Pour pouvoir utiliser les variables de configuration, il faut créer un fichier nommé “dates.settings.yml” dans le dossier “mon_module/config/install”.
Dans ce fichier, nous allons déclarer une variable :
Pour récupérer cette variable, il faut utiliser la méthode get :
Pour modifier cette variable, il faut utiliser la méthode set :
Il est possible de rendre administrable cette configuration via l’utilisation des formulaires de configuration Drupal en créant une classe qui étend la classe “ConfigFormBase” de Drupal 8.
9. Création d’un formulaire
Dans cette partie, nous allons voir comment créer un formulaire accessible depuis le back-office.
Dans un premier temps, nous allons créer un fichier MonForm.php dans /modules/custom/mon_module/src/Form/ avec le code suivant :
Voici les méthodes à ajouter dans notre classe “MonForm” :
getEditableConfigNames() : Permet d’obtenir le nom de la configuration
getFormId() : Retourne le nom unique du formulaire
buildForm() : Retourne le formulaire
validateForm() : Exécuter lors de la validation du formulaire
submitForm() : Exécuter lors de la soumission du formulaire
Pour récupérer et utiliser les données du formulaire et ainsi récupérer la valeur du champ “bienvenue_message”, il faut appeler la config avec son identifiant :
10. Mettre à jour le module custom vers Drupal 9
Drupal 9 étant construit sur Drupal 8, le principe de compatibilité des modules customs est similaire. La méthode de mise à jour est simple. Le module custom doit être scanné par le module contrib “Status Upgrade” afin de vérifier la qualité du code.
Après analyse, le module “Status Upgrade” identifie les erreurs qui nécessitent d’être corrigées avant mise à jour.
Plus d’information sur la sortie de Drupal 9 et la mise à jour de Drupal 8 et la mise à jour des statuts.
Pour plus d’information sur le statut de dépréciation d’un module il est possible de consulter cette page.