动态路由

使用 .routing.yml 文件定义路由是最常用的方式,但对于一些复杂的动态路由,可以使用 'route_callbacks' 属性来进行定义。

route_callbacks:
  - '\Drupal\example\Routing\ExampleRoutes::routes'

对应文件为 src/Routing/ExampleRoutes.php

也可以使用 service 中的方法

route_callbacks:
  - 'example.service:routes'

route_callbacks 是路由文件的顶级属性,以 Views 模块为例:

views.ajax:
  path: '/views/ajax'
  defaults:
    _controller: '\Drupal\views\Controller\ViewAjaxController::ajaxView'
  options:
    _theme: ajax_base_page
  requirements:
    _access: 'TRUE'

route_callbacks:
  - 'views.route_subscriber:routes'

动态路由方法需要返回一个包含 \Symfony\Component\Routing\Route 对象的数组,或一个 \Symfony\Component\Routing\RouteCollection 对象。以下是 src/Routing/ExampleRoutes.php 文件返回对象数组的示例:

namespace Drupal\example\Routing;

use Symfony\Component\Routing\Route;

/**
 * Defines dynamic routes.
 */
class ExampleRoutes {

  /**
   * [email protected]}
   */
  public function routes() {
    $routes = [];
    // Declares a single route under the name 'example.content'.
    // Returns an array of Route objects. 
    $routes['example.content'] = new Route(
      // Path to attach this route to:
      '/example',
      // Route defaults:
      [
        '_controller' => '\Drupal\example\Controller\ExampleController::content',
        '_title' => 'Hello'
      ],
      // Route requirements:
      [
        '_permission'  => 'access content',
      ]
    );
    return $routes;
  }

}

以下是返回 RoutingCollection 对象的示例:

namespace Drupal\example\Routing;

use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;

/**
 * Defines dynamic routes.
 */
class ExampleRoutes {

  /**
   * [email protected]}
   */
  public function routes() {
    $route_collection = new RouteCollection();

    $route = new Route(
      // Path to attach this route to:
      '/example',
      // Route defaults:
      [
        '_controller' => '\Drupal\example\Controller\ExampleController::content',
        '_title' => 'Hello'
      ],
      // Route requirements:
      [
        '_permission'  => 'access content',
      ]
    );
    // Add the route under the name 'example.content'.
    $route_collection->add('example.content', $route);
    return $route_collection;
  }

}

基于动态路由的动态路由

在一些情况下,可能需要创建基于动态路由的动态路由,例如为所有 Views 创建的页面添加Tab。这时需要通过对 onAlertRoutes 事件进行响应来实现,可参考 《Adding routes based on dynamic routes