Créer une action pour des mises à jours en masse personnalisées avec Drupal 8

Un coucher de soleil sur une ville

Drupal 8 permet de réaliser certaines actions en masse sur les contenus d'un site, comme par exemple publier ou dé-publier massivement des contenus, les positionner en haut des listes, etc. il peut être utile d'offrir à certains profils d'utilisateur certaines actions personnalisées liées aux spécificités de votre site, comme par exemple mettre en avant certains termes de taxonomie, changer la valeur d'un champ spécifique, et éviter ainsi aux utilisateurs de lourdes et fastidieuses opérations de mises à jour sur chacun des contenus à modifier.

Pour simplifier la gestion de ces contenus, nous pouvons donc créer des actions personnalisées, qui vont s'appuyer sur le plugin Action fourni par le coeur de Drupal, actions qui pourront être lancées massivement depuis une vue, à l'instar de ce que proposait le module Views bulk operation pour Drupal 7, et dont la migration d'une partie de ses fonctionnalités sur Drupal 8 est en cours de discussion.

Comment mettre en avant certains termes de taxonomy

Nous allons partir sur un cas d'usage qu'il n'est pas rare de rencontrer. Imaginons un site qui dispose d'un vocabulaire Keywords, et on souhaite pouvoir mettre en avant facilement certains mots clés qui seraient placés dans un bloc d'une vue dédiée.

Il suffit de créer un champ booléen (que nous allons appeler field_push) sur le vocabulaire Keywords et nous serons alors en mesure de distinguer quels mots clés on souhaite mettre en avant sur ce bloc, simplement en cochant ou non cette case sur chaque terme de taxonomy, et bien sûr de filtrer les mots clés sur ce champ dans une vue spécifique pour les récupérer.

Un champ booléen attaché aux termes de taxonomy Keywords

Nous pouvons alors éditer chaque mot-clé pour cocher ou non cette option. Mais pour un éditeur, ou un webmestre, cette tâche peut vite s'avérer fastidieuse. Il faut identifier les mots clés déjà mis en avant ou non, aller sur chacun d'eux puis les modifier selon le moment. Sur un site avec de nombreux mots clés, cela peut devenir très vite chronophage, voire source d'erreur.

Modifier les termes de taxonomy un par un

 

Création d'une vue d'administration

Nous pouvons créer une vue qui permettra aux éditeurs de gérer ces mots clés et leurs mises en avant. Ce qui leur permettra d'identifier rapidement quels mots clés sont mis en avant, et de pouvoir les modifier en masse en quelques clics.

Création d'une vue basée sur les termes de taxonomy

Nous créons donc une vue basée sur les termes de taxonomy, et nous limitons cette vue au vocabulaire Keywords.

Nous pouvons obtenir rapidement une vue listant les mots clés, leur statut vis à vis du champ booléen de mise en avant, et une liste d'action sur chaque terme de taxonomy pour pouvoir les modifier un par un.

Une vue d'administration basique des termes

Mais nous ne disposons pas sur notre vue de ce champ magique intitulé Bulk update qui nous permet de lancer des mises à jour en masse sur les items sélectionnés de notre vue, à l'instar de ce que l'on peut avoir sur une vue listant des contenus ou encore des utilisateurs.

Si nous ne disposons pas de ce champ Bulk update dans views pour les termes de taxonomy, c'est tout simplement parce que par défaut aucune action n'est encore définie sur ce type d'entité. Mais créer une action personnalisée, grâce au système de Plugin de Drupal 8 se réalise très simplement.

Créer une action personnalisée de mise à jour en masse

Nous allons créer un module que nous allons appeler My BO (nom système : my_bo) qui va nous fournir ces actions personnalisées. La structure de ce module est illustrée ci-dessous. Vous pouvez retrouver l'intégralité du code de ce module d'exemple sur ce dépôt GitHub.

Structure du module My BO

Dans le dossier Config du module, nous fournissons le schéma (my_bo.schema.yml) des configurations implémentées par celui-ci, à savoir les configurations de nos deux actions personnalisées : system.action.term_push_front.yml et system.action.term_unpush_front.yml.

Le dossier src/Plugin/Action va contenir les classes des deux Plugins actions créées.

 

Parcourons le contenu du fichier system.action.term_push_front.yml

# File system.action.term_push_front.yml
langcode: en
status: true
dependencies:
  module:
    - taxonomy
id: term_push_front
label: 'Push term in front'
type: taxonomy_term
plugin: term_push_front
configuration: {  }

Les éléments clés de la configuration de notre plugin sont :

  • Ses dépendances : nous déclarons le module taxonomy afin de pouvoir utiliser les termes de taxonomy
  • L'identifiant de la configuration (id) qui doit correspondre à l'identifiant inclus dans le nom du fichier
  • Le type d'entité sur laquelle le plugin va agir (ici les entités taxonomy_term)
  • Et enfin l'identifiant de la Classe du Plugin (clé plugin). C'est cet identifiant que nous déclarerons dans notre Classe

Parcourons le fichier de ce Plugin, le fichier src/Plugin/Action/TermPushFront.php

<?php

namespace Drupal\my_bo\Plugin\Action;

use Drupal\Core\Action\ActionBase;
use Drupal\Core\Session\AccountInterface;

/**
 * Push term in front.
 *
 * @Action(
 *   id = "term_push_front",
 *   label = @Translation("Push term in front"),
 *   type = "taxonomy_term"
 * )
 */
class TermPushFront extends ActionBase {

  /**
   * {@inheritdoc}
   */
  public function execute($entity = NULL) {
    /** @var \Drupal\taxonomy\TermInterface $entity */
    if ($entity->hasField('field_push')) {
      $entity->field_push->value = 1;
      $entity->save();
    }

  }

  /**
   * {@inheritdoc}
   */
  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
    /** @var \Drupal\taxonomy\TermInterface $object */
    $result = $object->access('update', $account, TRUE)
      ->andIf($object->field_push->access('edit', $account, TRUE));

    return $return_as_object ? $result : $result->isAllowed();
  }

}

Ce plugin Action étend simplement la Classe ActionBase et surcharge ses deux principales méthodes.

  • La méthode execute(), qui va executer l'opération voulue, ici changer la valeur de notre champ booléen field_push
  • La méthode access(), qui va vérifier que l'utilisateur lançant l'opération de mise à jour dispose bien des droits de modification sur l'entité en question et sur ce champ en particulier

Vous noterez dans les annotations du Plugin, son identifiant, celui là même déclaré dans le fichier de configuration du Plugin, ainsi que le type d'entité sur laquelle s'applique notre Plugin Action.

Après avoir activé ce module, nous disposons alors de ce champ de mise à jour en masse dans notre vue d'administration.

Champ views de mise à jour massive sur les termes de taxonomy

Et nous pouvons sélectionner les actions qui seront disponibles via ce champ de mises à jour.

Paramètres du champ de mise à jour massive

Une vue d'administration permettant des mises à jour en masse personnalisées

Nous disposons alors d'une vue permettant à certains utilisateurs de mettre à jour en masse les mots clés d'un site, sur un champ spécifique. Nous pouvons aussi noter que la création d'une action spécifique peut nous permettre d'autoriser certains utilisateurs à mettre à jour une propriété d'une entité, comme les termes de taxonomy, sans pour autant disposer des droits sur cette entité elle-même. Il suffit pour cela de personnaliser la méthode access() de notre plugin pour moduler ces droits.

Une vue d'administration de termes de taxonomy avec des mises à jour en masse possible

 

Aller plus loin avec des actions configurables

Nous avons créé, dans ce billet, des actions simples permettant de modifier la valeur d'un champ d'une façon prédéterminée. Les champ booléens s'y prêtent assez bien. Mais nous pouvons tout aussi facilement créer des actions configurables permettant par exemple de modifier la valeur d'un champ texte de façon massive, avec la saisie ou la sélection d'une nouvelle valeur au moment du lancement de la mise à jour. Pour ce faire, il suffit que le Plugin étende non plus la Classe ActionBase, mais la Classe ConfigurableActionBase qui nous permettra d''implémenter un formulaire permettant cette interaction. Mais ceci pourra faire l'objet d'un autre billet.

Vous avez un projet Drupal 8 en cours ou à venir, et vous recherchez des compétences Drupal 8 ? N'hésitez pas à consulter un Freelance expert Drupal 8 qui pourra très certainement vous accompagner dans votre projet.

 

Commentaires

Soumis par Florent Torregrosa (non vérifié) le 06/02/2017 à 22:08 - Permalien

Merci pour cet article.

Sur quelle version du noyau a-t-il été testé ?

J'ai récemment ouvert une issue dans le noyau https://www.drupal.org/node/2839351 pour l'ajout de VBO dans le noyau et je suis surpris par ta phrase "Si nous ne disposons pas de ce champ Bulk update dans views pour les termes de taxonomy, c'est tout simplement parce que par défaut aucune action n'est encore définie sur ce type d'entité."

En effet avec mon patch (core 8.2.*) qui initialement n'avait pas d'action derrière, j'avais bien le champ dans views et j'avais bien les cases à cocher mais pas d'action à sélectionner.

Du coup je suis surpris sur le fait de juste créer des actions pour les termes de taxonomie permet d'ajouter le champ.

Je m'étais inspiré du patch (que j'ai mis à jour par la suite) pour VBO sur les fichiers https://www.drupal.org/node/2413781.

Faudra que je re-test.

Salut,

Initialement le billet a été écrit sur la version 8.2.2, mais j'ai très exactement le même comportement avec la dernière version 8.2.6.

Soumis par Florent Torregrosa (non vérifié) le 07/02/2017 à 18:13 - Permalien

En réponse à par fabrice

En effet, après re-test, sans création d'un plugin de champ de views pour ajouter un champ VBO sur les termes de taxonomie, celui-ci est généré automatiquement s'il y a une action.

Je vais pouvoir mettre à jour les patchs pour VBO sur les fichiers et les termes de taxonomie...

Soumis par Romain (non vérifié) le 07/02/2017 à 12:11 - Permalien

Salut,

Merci pour l'article. J'ai un conseil à vous demander.
Je dois faire un update de masse sur un champ de taxonomie qui est une liste de termes (une catégorie).
Où puis-je trouver un exemple d'implémentation avec la classe ConfigurableActionBase ?

Soumis par François Schneider (non vérifié) le 07/06/2017 à 09:48 - Permalien

Bonjour,

Merci pour cet excellent article qui m'a permis de mettre en place une action en masse.

Je suis confronté au problème suivant : la case à cocher qui permet de tous sélectionner ne prend pas en compte les résultats dans les pages paginées, résultats mon action ne s'appliquent que sur les éléments de la page courante. Peut être que j'ai raté quelquechoses que cela s'applique à l'ensemble des pages ?

Soumis par W123456789 (non vérifié) le 31/08/2017 à 15:20 - Permalien

Bonjour,

Je suis débutant en Drupal 8, et j'essaye de suivre le tutoriel, mais en l'appliquant sur un Content Type (à la place d'une taxonomie), je ne vois pas le champ "Bulk update".

D'ailleurs, je n'arrive pas à comprendre d'où provient ce champ, j'ai créé un champ "Bulk Update" sur mon Content Type mais celui-ci le reconnaît comme un chemp de type "Content", et non "Taxonomy Term".

J'espère m'être bien exprimé ...

En tous cas merci pour ce tuto !

En fait le tuto porte sur une action de masse sur une taxonomie. Pour le faire sur un content type custom il suffit de changer le type d'entité impacté et le module dans fichier de configuration de l'action :

langcode: fr
status: true
dependencies:
module:
- custom_module
id: bulk_action_custom
label: "Custom bulk action"
type: node
plugin: bulk_action_custom
configuration: { }

Sur un node on a déjà plein d'actions par défaut, à la sélection du champ "Formulaire des opérations en masse sur les noeuds", on a bien l'action custom qui apparaît.

Bon, il ne me reste plus qu'à faire comprendre à Drupal que je veux être redirigé vers un form en utilisant ConfigurableActionBase, car pour l'instant je reste coincé dans la méthode execute() ...

Soumis par Sylvain (non vérifié) le 02/01/2020 à 18:38 - Permalien

Bonjour,
merci pour cet article clair et détaillé...
Je cherche à mettre en place quelque chose de similaire, mais en dynamique...
Je m'explique...
Je cherche à lier des ouvrages à des librairies... J'ai donc des ouvrages (ouvrage = node) et des librairies (librairie = custom entity)... Chaque user Drupal possède de 0 à une quantité illimité de librairies... J'aimerais créer une ou plusieurs actions (en fonction du nombre de librairies de l'utilisateur) qui permettent d'ajouter un ouvrage à une librairie (

Soumis par Sylvain (non vérifié) le 02/01/2020 à 18:44 - Permalien

Bonjour,
merci pour cet article clair et détaillé...
Je cherche à mettre en place quelque chose de similaire, mais en dynamique...
Je m'explique...
Je cherche à lier des ouvrages à des librairies... J'ai donc des ouvrages (ouvrage = node) et des librairies (librairie = custom entity)... Chaque user Drupal possède de 0 à une quantité illimité de librairies... J'aimerais créer une ou plusieurs actions (en fonction du nombre de librairies de l'utilisateur) qui permettent d'ajouter un ouvrage à une librairie (ajouter un ouvrage à une librairie = créer une autre entité custom)...
Si l'utilisateur connecté possède 2 librairies L1 et L2, il verrait apparaître 2 opérations "Ajouter à L1" et "Ajouter à L2".
Bien sûr, la perspective d'ajouter en masse plusieurs ouvrages à une librairie m'intéresse également...

Est-ce possible par ce procédé ? Par un autre ?

Merci encore...

Soumis par Laborouge (non vérifié) le 11/05/2020 à 11:03 - Permalien

Un grand merci pour cet article.
Encore une fois, tu m'as été d'une grande aide pour la prise en main d'une fonctionnalité que je ne maîtrisait pas.
Pour le retour d’expérience, j'ai pu générer une opération de génération de factures automatiques sur des commandes de Drupal Commerce.

Ajouter un commentaire