사용자 정의 사용자 탭을 작성하는 방법


9

entity. {entity_type} .canonical의 자손 인 모든 경로에 나타나는 새 사용자 정의 탭을 만들려고합니다. DeriverBase 클래스를 확장하려고 시도했는데 특히 getDerivativeDefinitions 메소드를 재정의했습니다. LocalTaskDefault를 확장하고 getRouteParameters 메소드를 대체하여 탭 자체를 작성했습니다. 이 탭은 www.mysite.com/user/1/ 또는 www.mysite.com/user/1/edit와 같은 표준 Drupal 사용자 경로를 방문 할 때 나타납니다. 그러나 www.mysite.com/user/1/subscribe와 같은 새로운 사용자 지정 사용자 경로를 추가하면 탭이 나타나지 않습니다. 사용자 지정 경로에서 로컬 메뉴 작업을 정의하는 특별한 방법이 있습니까? 코드 샘플 :

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

도움을 주셔서 감사합니다.


/ devel route / local 작업으로 devel 이하는 일에 매우 가깝게 들리므로 구현 방법을 살펴 보는 것이 좋습니다.
Berdir

@ Berdir 그 시작점이지만 여전히 뭔가 빠진 것 같습니다.
tflanagan

사용자 정의 탭 설정으로 'yourmodule.links.task.yml'파일을 추가하려고 했습니까?
Andrew

답변:


7

Berdir이 제안한 것처럼 Devel 모듈과 그것을 구현하는 방법을 볼 수 있습니다. 다음 코드는 Devel에서 "추출"되었습니다.

1) 경로 생성

내부 및 내부에 mymodule.routing.yml 파일을 작성하여 라우트 콜백을 정의하십시오 (동적 라우트 작성에 사용됨)

route_callbacks:
  - '\Drupal\mymodule\Routing\MyModuleRoutes::routes'

src / Routing에서 동적 경로를 생성하기 위해 MyModuleRoutes 클래스를 만듭니다.

<?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

src / Plugin / Derivative에서 동적 경로를 생성하기 위해 MyModuleLocalTasks 클래스를 작성하십시오.

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

}

3
이것은 내가 구현 한 것과 매우 유사했습니다. RouteMatchInterface $ route_match를 전달하면 문제가 해결되었습니다. 거기서부터 엔티티 객체를 컨트롤러에 사용할 수있었습니다.
tflanagan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.