Làm cách nào để tạo tab người dùng tùy chỉnh?


9

Tôi đang cố gắng tạo một tab tùy chỉnh mới xuất hiện trên tất cả các tuyến đường là hậu duệ của thực thể. {Ent_type} .canonical. Tôi đã thử mở rộng lớp DeriverBase, đặc biệt ghi đè phương thức getDerivativeDefDefs. Tôi đã tự tạo tab bằng cách mở rộng LocalTaskDefault và ghi đè phương thức getRouteParameter. Tab xuất hiện khi bạn truy cập đường dẫn người dùng Drupal tiêu chuẩn, chẳng hạn như www.mysite.com/user/1/ hoặc www.mysite.com/user/1/edit. Tuy nhiên, khi chúng tôi thêm các tuyến người dùng tùy chỉnh mới của mình như www.mysite.com/user/1/subscribe, không có tab nào xuất hiện. Có cách nào đặc biệt để xác định các tác vụ menu cục bộ trên các tuyến tùy chỉnh không? Một mẫu mã:

 $this->derivatives['recurly.subscription_tab'] = [
  'title' => $this->t('Subscription'),
  'weight' => 5,
  'route_name' => 'recurly.subscription_list',
  'base_route' => "entity.$entity_type.canonical",
];

foreach ($this->derivatives as &$entry) {
  $entry += $base_plugin_definition;
}

Cảm ơn trước bất kỳ sự giúp đỡ.


Âm thanh rất gần với những gì phát triển đang làm với nó / tuyến đường phát triển / nhiệm vụ địa phương, tôi khuyên bạn nên xem cách nó thực hiện điều đó.
Berdir

@Berdir đó là điểm khởi đầu nhưng dường như tôi vẫn còn thiếu một cái gì đó.
tflanagan

Bạn đã thử thêm tệp 'yourmodule.links.task.yml' với các cài đặt cho tab tùy chỉnh của mình chưa?
Andrew

Câu trả lời:


7

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;
  }

}

3
Điều này rất giống với những gì tôi đã thực hiện. Vượt qua trong RouteMatchInterface $ route_match là cách giải quyết vấn đề của tôi. Từ đó đối tượng thực thể của tôi đã có sẵn cho bộ điều khiển của tôi.
tflanagan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.