跳转到主要内容
ryerh 提交于 8 October 2014

原文链接:Altering existing routes and adding new routes based on dynamic ones

一条路由 ―― 不管是静态地定义在 YAML 文件(参考示例)中,还是动态地创建在使用动态路由中,都可以被替换。你可以使用一个触发了 RoutingEvents::ALTER事件的 EventSubscriber 对象来修改一个 RouteCollection。

替换现有路由

创建路由之后(例如一个模块被启用或缓存被清空的时候),RoutingEvent::ALTER事件将触发路由替换过程,\Drupal\Core\Routing\RouteSubscriberBase基类包含了对该事件的监听器。你可以实现 替换路由(RouteCollection $collection) 中的方法以实现对现有路由的覆盖。 下面这个例子替换了用户模块中的两条路由,在你的模块中使用 src/Routing/RouteSubscriber.php这个文件。

<?php

/**
 * @file
 * Contains \Drupal\example\Routing\RouteSubscriber.
 */

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}
   */
  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');
      }
    }
  }

}
?>
\Drupal\example\Routing\RouteSubscriber::alterRoutes

方法是一个订阅者对象,因为它继承自 RouteSubscriberBase。因此,该类的对象必须注册事件发布服务。 在你的模块中使用 example.services.yml文件(example的名字由你决定)。

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

基于现有动态路由添加新路由

你可以使用 alterRoutes()方法添加动态路由。如果添加的路由比较独立,那么推荐的方法是使用简洁的路由回调方案而不是实现一个订阅者类。但是,如果添加的路由需要依赖于别的动态路由,那么你就得实现一个继承自 RouteSubscriberBase的类了。确保在实现 getSubscribedEvents()方法的时候权衡好分量。the configuration translation RouteSubscriber 有个很好的例子。