Theo đề xuất của Berdir, bạn có thể xem mô-đun Devel và cách nó thực hiện điều đó. Đoạn mã sau được "trích xuất" từ Devel
1) Tạo các tuyến đường
Tạo tệp mymodule.routing.yml trong và bên trong xác định một cuộc gọi lại tuyến đường (được sử dụng để tạo các tuyến đường động)
route_callbacks:
- '\Drupal\mymodule\Routing\MyModuleRoutes::routes'
Tạo lớp MyModuleRoutes để tạo các tuyến động của bạn trong 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) Tạo các tác vụ cục bộ động
Tạo tập tin mymodule.links.task.yml và bên trong xác định một bộ chuyển đổi
mymodule.tasks:
class: \Drupal\Core\Menu\LocalTaskDefault
deriver: \Drupal\mymodule\Plugin\Derivative\MyModuleLocalTasks
Tạo lớp MyModuleLocalT task để tạo các tuyến động của bạn trong 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) Tạo bộ điều khiển
Tạo lớp MyModuleContoder trong src / Controller
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;
}
}