Pour créer un type de contenu à l'aide d'un module, il faut rajoute les fichiers yaml qui décrivent ce type de contenu et tous ses champs dans le répertoire config/install du module.
Créer les fichiers yaml peut être très laborieux. C'est pourquoi il est conseillé de créer le type de contenu avec l'interface graphique puis de les exporter à l'aide de l'outil en ligne de commande drupal console. Pour savoir comment installer cet outil, lisez l'article "installer drupal console"
Exporter des types de contenu vers un module avec drupal console
La marche à suivre est la suivante :
Créer votre type de contenu et ses champs comme expliquer dans l'article "Créer de nouveaux types de contenu"
Si ce n'est pas déjà fait, créer un module avec la commande drush gen module. Cette commande est expliquée dans l'article "Créer le squelette d'un module"
Utiliser Drupal console pour copier les fichiers yaml dans le dossier config/install de votre module à l'aide de la commande drupal config:export:content:type nom_type_de_contenu.
Drupal console vous demande alors
- le nom du répertoire,
- si vous voulez copier les fichiers dans un répertoire optionnel. Si vous répondez oui, les fichiers seront copiés dans le répertoire config/optional. Un problème d'importation du type de contenu qui surviendrait lors de l'activation du module, n'empêcherait pas l'activation du module.
- si vous voulez copier les configurations sans la clé unique du type de contenu. Un éventuel type de contenu qui porterait la même clé et qui serait présent sur le site d'import serait mis à jour lors de l'activation du module. Il vaut mieux répondre non.
- si vous voulez copier les configurations sans la clé unique du site. A moins de vouloir installer ce type de contenu sur une copie de ce site, il faut répondre oui
- inclure les dépendances dans le fichier info.yml du module ce qui est nécessaire. Il faut donc répondre yes à cette question.
Attention, il y a un petit bug. Lors de la copie des fichiers, drupal console rajoute deux fois l'extension yml à certains fichiers. Il faut donc chercher dans le fichier config/install et corriger le nom de ces fichiers.
Pensez à vérifier les dépendances générées dans les fichiers des types de contenu.
Enfin, si vous souhaitez que les types de contenus soit supprimés lors de la désinstallation du module, la doc officielle propose de rajouter des dépendances vers le module dans le fichier node.type.nom_type.yml. Pour cela, rajouter la clé suivante :
dependencies:
enforced:
module:
- nom de votre module
Attention. Si l’utilisateur a créé des contenus de ce type, puis, qu’il désinstalle le module, alors ils se retrouvera avec des contenus sans type. Pour pallier à ce problème il y a deux solutions :
- Supprimer automatiquement tous les contenus de ce type
- Empêcher la suppression du module tant que l’utilisateur n’a pas supprimé tous les contenus de ce type
Supprimer automatiquement tous les contenus de ce type
Cette solution est assez simple mais ne permet pas à l’utilisateur de choisir s’il veut ou non supprimer les contenus.
- Commencer par créer un fichier nommodule.install à la racine de votre module
- Créer une fonction nommodule_uninstall() et y ajouter le code qui supprime les contenus d’un certains types
// fichier nommodule.install à la racine du module
function premiermo_uninstall() {
$livres=\Drupal::entityTypeManager()->getStorage('node')->loadByProperties(['type' => 'livre']);
foreach ($livres as $livre){
$livre->delete();
}
}
L'article "supprimer une entité" détaille la méthode utilisée ci-dessus.
Empêcher la suppression du module tant que l’utilisateur n’a pas supprimé tous les contenus de ce type
Cette méthode est plus complexe, mais elle permet à l’utilisateur de choisir s’il veut supprimer les contenus. Dans l'exemple ci-dessous, le module s'appelle premiermo et des types de contenu auteur et livre ont été rajouté.
Créer la classe validator dans le répertoire src
Il faut créer une classe qui implémente l’interface ModuleUninstallValidatorInterface dans le répertoire src du module. Le fichier doit porter le même nom que la classe. NommoduleUninstallValidator.php.
Dans ce fichier on commence par utiliser le namespace du module puis utiliser les classes :
- EntityTypeManagerInterface pour charger les types de contenu
- StringTranslationTrait et TranslationInterface pour pouvoir utiliser les méthodes de traduction
- ModuleUninstallValidatorInterface pour avoir une fonction de validation de la désinstallation d’un module
//Fichier PremiermoUninstallValidator situé dans le dossier modules/premiermo/src
<?php
namespace Drupal\premiermo;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleUninstallValidatorInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
Dans la classe nouvellement créé, on rajoute une méthode qui permet de vérifier si des nodes du type recherché existe :
protected function hasNodes($type) {
$nodes = $this->entityTypeManager->getStorage('node')->getQuery()
->condition('type', $type)
->accessCheck(FALSE)
->range(0, 1)
->execute();
return !empty($nodes);
Ensuite on rajoute la méthode validate
public function validate($module) {
$reasons = [];
if ($module == 'premiermo') {
// The auteur and livre node type is provided by the Premiermo module. Prevent uninstall
// if there are any nodes of that type.
if ($this->hasNodes("auteur")) {
$reasons[] = $this->t('To uninstall premiermo, delete all content that has the Auteur content type');
}
if ($this->hasNodes("livre")) {
$reasons[] = $this->t('To uninstall PremierMo, delete all content that has the Livre content type');
}
}
return $reasons;
}
Maintenant que notre validator existe, il faut le déclarer dans le fichier premiermo.services.yml. Comme pour tout fichier yml, pensez à vider le cache
services:
premiermo.uninstall_validator:
class: Drupal\premiermo\PremiermoUninstallValidator
tags:
- { name: module_install.uninstall_validator }
arguments: ['@entity_type.manager', '@string_translation']
La propriété tags n’est pas le fruit du hasard. L’nterface Drupal\Core\Extension\ModuleUninstallValidatorInterface indique le nom à utiliser
Les arguments correspondent aux éléments à transmettre au constructeur de la classe. Ici ces éléments commencent par des @, donc il s’agit d’autres services
La doc Drupal sur le fichier nommodule.services.yml
Cet exemple a été construit à partir du module du core book.