根据Berdir的建议,您可以查看Devel模块及其实现方式。以下代码是从Devel中“提取”的
1)创建路线
在文件的内部和内部创建文件mymodule.routing.yml,以定义路由回调(用于创建动态路由)
route_callbacks:
- '\Drupal\mymodule\Routing\MyModuleRoutes::routes'
创建类MyModuleRoutes以在src / Routing中生成您的动态路由
<?php
namespace Drupal\mymodule\Routing;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
class MyModuleRoutes implements ContainerInjectionInterface {
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager')
);
}
public function routes() {
$collection = new RouteCollection();
foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
if ($entity_type->hasLinkTemplate('canonical')) {
$route = new Route("/mymodule/$entity_type_id/{{$entity_type_id}}");
$route
->addDefaults([
'_controller' => '\Drupal\mymodule\Controller\MyModuleController::doStuff',
'_title' => 'My module route title',
])
->addRequirements([
'_permission' => 'access mymodule permission',
])
->setOption('_mymodule_entity_type_id', $entity_type_id)
->setOption('parameters', [
$entity_type_id => ['type' => 'entity:' . $entity_type_id],
]);
$collection->add("entity.$entity_type_id.mymodule", $route);
}
}
return $collection;
}
}
2)创建动态本地任务
创建文件mymodule.links.task.yml并在其中定义派生程序
mymodule.tasks:
class: \Drupal\Core\Menu\LocalTaskDefault
deriver: \Drupal\mymodule\Plugin\Derivative\MyModuleLocalTasks
创建类MyModuleLocalTasks以在src / Plugin / Derivative中生成您的动态路由
<?php
namespace Drupal\mymodule\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class MyModuleLocalTasks extends DeriverBase implements ContainerDeriverInterface {
protected $entityTypeManager;
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
$this->entityTypeManager = $entity_type_manager;
}
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static(
$container->get('entity_type.manager')
);
}
public function getDerivativeDefinitions($base_plugin_definition) {
$this->derivatives = array();
foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
if ($entity_type->hasLinkTemplate('canonical')) {
$this->derivatives["$entity_type_id.mymodule_tab"] = [
'route_name' => "entity.$entity_type_id.mymodule",
'title' => t('Mymodule title'),
'base_route' => "entity.$entity_type_id.canonical",
'weight' => 100,
] + $base_plugin_definition;
}
}
return $this->derivatives;
}
}
3)创建控制器
在src / Controller中创建类MyModuleController
namespace Drupal\mymodule\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
class MyModuleController extends ControllerBase {
public function doStuff(RouteMatchInterface $route_match) {
$output = [];
$parameter_name = $route_match->getRouteObject()->getOption('_mymodule_entity_type_id');
$entity = $route_match->getParameter($parameter_name);
if ($entity && $entity instanceof EntityInterface) {
$output = ['#markup' => $entity->label()];
}
return $output;
}
}