Come posso creare schede utente personalizzate?


9

Sto cercando di creare una nuova scheda personalizzata che appare su tutte le rotte che sono discendenti dell'entità. {Entity_type} .canonical. Ho provato ad estendere la classe DeriverBase, in particolare sovrascrivendo il metodo getDerivativeDefinitions. Ho creato la scheda stessa estendendo LocalTaskDefault e sovrascrivendo il metodo getRouteParameters. La scheda appare quando visiti un percorso utente Drupal standard come www.mysite.com/user/1/ o www.mysite.com/user/1/edit. Tuttavia, quando aggiungiamo i nostri nuovi percorsi utente personalizzati come www.mysite.com/user/1/subscribe, non vengono visualizzate schede. Esiste un modo speciale per definire attività di menu locali su percorsi personalizzati? Un esempio del codice:

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

Grazie in anticipo di qualsiasi aiuto.


Sembra molto vicino a ciò che lo sviluppo sta facendo con il suo / percorso di sviluppo / compito locale, ti suggerisco di dare un'occhiata a come lo sta implementando.
Berdir,

@Berdir quello era il punto di partenza ma mi sembra ancora che manchi qualcosa.
tflanagan,

Hai provato ad aggiungere il file "yourmodule.links.task.yml" con le impostazioni per la tua scheda personalizzata?
Andrew,

Risposte:


7

Come suggerito da Berdir puoi guardare il modulo Devel e come lo sta implementando. Il seguente codice è stato "estratto" da Devel

1) Crea i percorsi

Creare il file mymodule.routing.yml dentro e dentro definire un callback di route (che viene utilizzato per creare le route dinamiche)

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

Crea la classe MyModuleRoutes per generare i tuoi percorsi dinamici in 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) Creare le attività locali dinamiche

Crea il file mymodule.links.task.yml e all'interno definisci un deriver

mymodule.tasks:
  class: \Drupal\Core\Menu\LocalTaskDefault
  deriver: \Drupal\mymodule\Plugin\Derivative\MyModuleLocalTasks

Crea la classe MyModuleLocalTasks per generare i tuoi percorsi dinamici in 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) Creare il controller

Crea la classe MyModuleController in 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
Questo è stato molto simile a quello che ho finito per implementare. Passare in RouteMatchInterface $ route_match è stata la soluzione al mio problema. Da lì il mio oggetto entità era disponibile per il mio controller.
tflanagan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.