How to alter existing routes in Drupal 8 and Drupal 9

lakshmi , Credit to  volkotech-solutions Jun 05

Any route, whether statically defined in a YAML file or dynamically defined, can be altered. After building routes (for example, when a module is enabled or caches are cleared), the RoutingEvents::ALTER event starts the route alters the process. The \Drupal\Core\Routing\RouteSubscriberBase class contains an event listener that listens to this event. Alter existing routes by implementing the RouteSubscriberBase class's alterRoutes(RouteCollection $collection) method.


For example, alters the routes of the User module and any custom modules. This blog explains the following scenarios,

  • To change user login path '/user/login' to '/login'
  • To change path of route welcome_message.front_page to /wel/mes.
  • Always deny access to '/user/logout'.
  • Disable access to the user registration page.
  • Remove user password reset page.
  • To alter the title of the site page.

Create the modulename.info.yml

name: Alter Existing Routes
description: Custom module for altering routes of modules.
type: module
core_version_requirement: ^8 || ^9

Create src/Routing/RouteSubscriber.php

How do change the path of a route?

For example, need to change the user login path '/user/login' to '/login' then write the following condition in the alterRoutes function. The function setPath() Sets the pattern for the path.

if ($route = $collection->get('user.login')) {
     $route->setPath('/login');
   }

How to deny or disable or remove the path of a route?

Using Route::setRequirement() to set custom access checks on any route within the alterRoutes function and the second parameter of setRequirement() is a set to be TRUE or FALSE based on requirements.

For example, Remove the user password reset page then write the following condition in the alterRoutes function.

if ($route = $collection->get('user.pass')) {
     $route->setRequirement('_access', 'FALSE');
   }

How to change the title of the page?

Using Route::setDefault() Sets a default value of any route within the alterRoutes function. For example Change the title of the contact site page using the following condition in the alterRoutes function, here the second parameter of Route::setDefault() is a new title of the page.

if ($route = $collection->get('contact.site_page')) {
     $route->setDefault('_title', 'Contact us');
   }

This example alters the different routes of the different modules. Place the following code in  src/Routing/RouteSubscriber.php file in your module.

<?php
 
/**
* @file
* Contains \Drupal\modulename\Routing\RouteSubscriber.
*/
 
namespace Drupal\modulename\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 path '/user/login' to '/login'.
   if ($route = $collection->get('user.login')) {
     $route->setPath('/login');
   }
   // Change path of route welcome_message.front_page to /wel/mes.
   if ($route = $collection->get('welcome_message.front_page')) {
       $route->setPath('/wel/mes');
     }
   // Always deny access to '/user/logout'.
   // Note that the second parameter of setRequirement() is a string.
   if ($route = $collection->get('user.logout')) {
     $route->setRequirement('_access', 'FALSE');
   }
   // Disable access to the registration page.
   if ($route = $collection->get('user.register')) {
     $route->setRequirement('_access', 'FALSE');
   }
 
   // Remove user password reset page.
   if ($route = $collection->get('user.pass')) {
     $route->setRequirement('_access', 'FALSE');
   }
   // alter title of site page.
   if ($route = $collection->get('contact.site_page')) {
     $route->setDefault('_title', 'Contact us');
   }
 }
 
}

Create modulename.services.yml file

In Drupal 8/9, we must create a service that extends RouteSubscriberBase to alter existing routes.

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

Conclusion:

In altering existing routes of the core module and custom module in Drupal 8/9, we must create a service that extends RouteSubscriberBase.

 

Comments