Aiguillage férovière de trois rails.
  • 19/02/2020
  • 0 commentaire

Voici le premier article du nouveau format mis en place sur ce site. C'est un format de type Quickie où je vais parler, démontrer, résoudre une problématique d'un cas réel.

Dans ce premier exemple nous allons voir comment altérer une route existante, d'un module contrib ou du cœur pour changer l'url, la callback, les permissions ...

Pour commencer cet article traiteras des altérations de routes existantes. Si vous souhaitez créer des routes personnalisées vous pouvez vous rendre sur d'autres article ou j'explique comment créer des nouvelles entrées dans Drupal 8.

Exemple :

I) Concept du RouteSubscriber

Pour altérer des routes, Drupal lance l'événement RoutingEvents::ALTER qui est écouté par les classes étendant RouteSubscriberBase. Il suffit de créer un service qui souscrit à cet événement et qui étends la classe ci dessus et d'y injecter notre logique métier. Pour en apprendre plus sur les événements, leur déclaration, altération, souscription ... vous pouvez lire cette article. [FR]

II) Déclaration du service

Pour altérer une route existante il faut passer par l'instanciation d'un service de type routeSubscriber. Pour cela il faut utiliser ou créer un fichier mymodule.services.yml à la racine d'un module.

Voici un exemple de ce fichier :

services:
  mymodule.route_subscriber:
    class: Drupal\mymodule\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

Dans un fichier mymodule.services.yml, la première clef est toujours le mot "services". Ensuite on déclare un nom de service puis les options et attributs associés à ce dernier.

Je ne sais pas si il y a une convention de nommage officiel mais d'après mon expérience les noms de services son composés du nom du module suivi du nom du service. Quand c'est possible on met le type de service après le nom du module. Voici quelques exemples :

  • mymodule.route_subscriber
  • mymodule.twig.custom_extension
  • ...

III) Création de la classe du RouteSubscriber

Dans le dossier de votre module, il faut créer une classe avec le nom indiqué dans le fichier ci-dessus (ici RouteSubscriber.php) dans le dossier src/Routing.

Voici un exemple :

<?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  protected function alterRoutes(RouteCollection $collection) {
    
    // Change the callback
    if ($route = $collection->get('my.route.to.alter')) {
      $route->setDefault('_form', '\Drupal\mymodule\Form\MyForm');
    }

    // Change path
    if ($route = $collection->get('mymodule.route.default')) {
        $route->setPath('/mymodule/route/path');
    }
  }

}

Les éléments importants sont :

  • Votre classe doit étendre RouteSubscriberBase
  • Vous devez faire appel à la méthode alterRoute et mettre votre logique à l'intérieur
  • Pour modifier une route il faut utiliser l'objet $collection et récupérer la route via son nom machine
  • Vider les caches à chaque modification pour que ce soit pris en compte

Voici en vrac quelques méthode rapide pour altérer une route :

  • $route->setDefault('_controller', '\Drupal\mymodule\Controller\MyController');
     
    • Modification du contrôleur, le form .. appelé par la route.
  • $route->setPath('/my/custom/paht');
    • Modification du chemin de la route

  • $route->setRequirement('_permission', 'my permission');
    • Ajoute une permission pour contrôler les accès à la page

  • $route->setOption('_admin_route', TRUE);
    • Permet d'ajouter une option à une route. Ici on indique que la route est une page d'administration.

 

IV) Pour aller plus loin

Pour plus d'informations voici les liens vers la documentation officielle du RouteSubscriber.

Voici également le lien de la documentation sur l'altération des routes.

 

V) Conclusion

Comme expliqué en début d'article, ce nouveau format va être développé sur ce blog et ne rentrera pas trop dans les détails. Le but est de partir d'une problématique réelle et d'aller au plus vite pour proposer une solution qui répond à la logique de Drupal 8.

Si vous avez des idées ou des besoins spécifiques qui pourrait faire l'objet d'un quickie, vous pouvez m'en faire part par commentaire ou directement via Twitter. Vous pouvez également me contacter pour des recommandations, améliorations concernant cet article surtout si il s'agît d'erreur !