Altering existing routes and adding new routes based on dynamic ones

Last updated on
4 March 2017

Any route - whether statically defined in a YAML file, as seen in the introductory example, or a dynamic route as described in Providing dynamic routes - can be altered. You can do so by modifying a RouteCollection using an EventSubscriber triggered by the RoutingEvents::ALTER event.

Altering existing routes

After building routes (e.g. when a module is enabled or when caches are cleared), the RoutingEvents::ALTER event triggers the route alter process. The \Drupal\Core\Routing\RouteSubscriberBase class contains an event listener that listens to this event. You can alter existing routes by implementing the alterRoutes(RouteCollection $collection) method of this class.

This example alters two different routes of the User module. Use a src/Routing/RouteSubscriber.php file in your module.

namespace Drupal\example\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');
    }
    // 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');
    }
  }

}

The \Drupal\example\Routing\RouteSubscriber::alterRoutes method is an event subscriber because it extends RouteSubscriberBase. Therefore, the class must be registered as an event subscriber service.

Use a example.services.yml file in your module (if the module is named example).

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

Adding routes based on existing dynamic routes

You can use the alterRoutes() method to add dynamic routes as well. If your dynamic routes are standalone, the preferred method is not to implement this class and event subscriber but instead use the simpler route_callbacks solution. However, if the dynamic routes are dependent on other dynamic routes, you'll need to implement a class extending from RouteSubscriberBase. Make sure to adjust the weight of the event subscription in a getSubscribedEvents() method implementation. A real example can be found in the configuration translation RouteSubscriber.