Saturday 13 April 2019

Alter Path/Route in Drupal 8

In Drupal 7, path can be altered with the help of hook "hook_menu_alter()" but in Drupal 8 hook_menu is no longer exists so to alter the path in Drupal 8, we have to write a route subscriber.

To change the route behaviour, we need to use a service called RouteSubscriber.

  1. We need to tell Drupal that we have this service,
  2. Need to create the right class
Alter the path user/login, user/password handled by user module and remove /search handled by the Search module.
Create a custom module with custom service an RouteSubscriber.

Custom module: route_alter
create a route_alter.services.yml with custom service.

route_alter.info.yml
name: Alter Route
description: 'Alter custom or contributed Route'
type: module
core: 8.x

package: custom

route_alter.services.yml
services:
  route_alter.route_subscriber:
    class: Drupal\route_alter\Routing\AlterCustomRouteSubscriber
    tags:
      - { name: event_subscriber }

To implement RouteSubscriber, create file AlterCustomRouteSubscriber.php in directory src > Routing create class AlterCustomRouteSubscriber within this file.
Copy and paste below code in the above mentioned file.

<?php

/**
 * @file
 * Contains \Drupal\route_alter\Routing\AlterCustomRouteSubscriber.

 */

namespace Drupal\route_alter\Routing;

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

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

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {
    // Change path '/user/login' to '/login'.
    if ($route = $collection->get('user.login')) {
      $route->setPath('/login');
    }
    // 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');
    }
    // Remove the /search route.
    $collection->remove('search.view');
  }
}

Explanation for above code
\Drupal\route_alter\Routing\RouteSubscriber::alterRoutes method is an event subscriber because it extends RouteSubscriberBase. That's why class AlterCustomRouteSubscriber must be registered as an event subscriber service as in file route_alter.services.yml
  • With the help of alterRoutes method, dynamic routes can also added. 
  • If dynamic routes are standalone, use simpler route_callbacks solution and do not implement this class and event subscriber. 
  • If dynamic routes are dependent on other dynamic routes, then need to implement a class extending from RouteSubscriberBase

No comments:

Post a Comment