In einem früheren Tutorial haben wir uns das Drupal 8 -Plugin -System angesehen und wie wir unseren eigenen benutzerdefinierten Plugin -Typ erstellen. Wir haben gesehen, dass ein Großteil der über _info -Hooks in Drupal 7 deklarierten Funktionalität durch diese Plugins ersetzt wurde. Unser Anwendungsfall war sehr grundlegend und ermöglichte es, dass jeder Instanz über eine neue Plugin -Klasse und das zugehörige Formular manuell deklariert wird.
.
Aber was ist, wenn wir solche Instanzen brauchten dynamisch dynamisch von einigen Faktoren, die außerhalb unseres kleinen Subsystems extern sind? Wenn Sie beispielsweise _info -Hooks in Drupal 7 deklarieren, können wir eine Liste von etwas erhalten, über sie schauen und ein neues Element im zurückgegebenen Array für jedes einzelne etwas
deklarieren. Das Menüsystem erledigt dies, um einen neuen Block für jedes Menü bereitzustellen, das entweder mit Drupal -Kern geliefert wird oder später über die Benutzeroberfläche erstellt wird.Was ist also mit Drupal 8? Wir haben gesehen, dass wir für jedes Plugin eines bestimmten Typs eine andere PHP -Klasse deklarieren müssen. Um einen neuen Block zu erstellen, brauchen wir eine neue Klasse. Um einen weiteren Block zu erstellen, brauchen wir eine andere Klasse. Wo sehen wir in Drupal 7 das Looping ? Die kurze Antwort darauf lautet: Innerhalb eines -Plugin -Ableitung
.In diesem Artikel werden wir die lange Antwort darauf untersuchen und lernen, was Ableitungen sind und wie wir sie verwenden können. Für letztere erstellen wir ein Beispiel im Demo -Modul, das in diesem Git -Repository zu finden ist und das uns hoffentlich helfen sollte, zu verstehen, was vor sich geht. Für ein etwas komplexeres Beispiel ist das Menüsystem großartig, da es für jede seiner Menüs einen einzelnen Block bietet (ähnlich wie bei Drupal 7, aber mit Plugins).
Was wir tun werden, ist eigentlich sehr einfach. Wir werden grundlegende Knotenblockfunktionen implementieren, mit denen wir für alle Artikelknoten auf unserer Website einen Block haben werden. Lächerlich? Sicher. Sollten wir dies für alle Knoten auf unserer Website tun? Auf keinen Fall! Es ist jedoch eine sehr grundlegende Implementierung, um die Dinge kurz zu halten und die Verwendung der Pluginderivate zu demonstrieren.
Plugin -Derivate sind die Art und Weise, wie ein Plugin eines bestimmten Typs im System als mehrere Instanzen von sich selbst dargestellt werden kann. Mit anderen Worten kann ein Plugin auf eine Deriver -Klasse verweisen, die für die Bereitstellung einer Liste von Plugin -Definitionen verantwortlich ist, die auf dem anfänglichen Plugin basieren (starten Sie die gleiche Basisdefinition), haben jedoch eine geringfügige unterschiedliche Konfigurations- oder Definitionsdaten. Das oben genannte SystemMenublock ist ein gutes Beispiel. Es ist ein einzelnes Plugin, das so viele Derivate hat wie Menüs auf der Website.
etwas tiefer gehen, wenn eine Liste aller Plugins eines bestimmten Typs angefordert wird, verwendet der Plugin -Manager seinen Erkennungsmechanismus, um alle Plugins dieser Art zu laden. Wenn dieser Mechanismus mit dem DerivatediscoveryDecorator dekoriert ist, kann der Manager auch Derivate abrufen. Zu diesem Zweck sucht die Derivaterkennung für eine Ausleitungsklasse für jedes Plugin und fragt sie nach dieser Liste, wenn sie eine findet.
Manager vom Typ Plugin, die die Standard -Basisklasse für die Standard -PluginManager erweitern, sollten normalerweise den Deseivat -Entdeckungsmechanismus aufweisen, der die Standard -Entdeckung dekoriert (Annotationen). Dies ist das häufigste Muster im Drupal -Kern -Plugin -System: Annotatierte Entdeckung, die von Derivaten verpackt ist.
Jetzt, da wir wissen, wie wichtig die Rolle von Plugin -Derivaten ist, lassen Sie uns unsere erste Ausleitungsklasse erstellen, die von unserem Block -Plugin verwendet wird (das wir in einer Minute erstellen werden).
in SRC/Plugin/Derivat/nodeBlock.php des Demo -Moduls haben wir Folgendes:
<?php /** * @file * Contains \Drupal\demo\Plugin\Derivative\NodeBlock. */ namespace Drupal\demo\Plugin\Derivative; use Drupal\Component\Plugin\Derivative\DeriverBase; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides block plugin definitions for nodes. * * @see \Drupal\demo\Plugin\Block\NodeBlock */ class NodeBlock extends DeriverBase implements ContainerDeriverInterface { /** * The node storage. * * @var \Drupal\Core\Entity\EntityStorageInterface */ protected $nodeStorage; /** * Constructs new NodeBlock. * * @param \Drupal\Core\Entity\EntityStorageInterface $node_storage * The node storage. */ public function __construct(EntityStorageInterface $node_storage) { $this->nodeStorage = $node_storage; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, $base_plugin_id) { return new static( $container->get('entity.manager')->getStorage('node') ); } /** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { $nodes = $this->nodeStorage->loadByProperties(['type' => 'article']); foreach ($nodes as $node) { $this->derivatives[$node->id()] = $base_plugin_definition; $this->derivatives[$node->id()]['admin_label'] = t('Node block: ') . $node->label(); } return $this->derivatives; } }
Alle unsere Klasse müssen implementiert werden, ist das Ausgangsinterface und die implementieren der beiden Methoden. Wir verwenden stattdessen das ContainerIverInterface, da wir unseren Ausleitungsbehälter aufmerksam machen möchten. Warum? Da wir die Abhängigkeitsinjektion verwenden, um den Entitätsmanager von Drupal zu laden, damit wir auf den Knotenspeicher zugreifen können (dies ist, was der Konstruktor und die Methode create () tun). Darüber hinaus erstreckt sich unsere Deriver -Klasse von der Deriverbase -Klasse, da dies bereits eine der erforderlichen Methoden erledigt (getDerivatedeFinition ()).
Schließlich ist GetderivatedEFinitions () die Methode, die für die Bereitstellung einer Reihe von Plugin -Definitionen verantwortlich ist, die aus dem Plugin stammen, das diese Klasse verwendet. Es empfängt die $ Base_plugin_definition als Argument (die Definition des tatsächlichen Plugins, das diesen Deriver verwendet), und wir verwenden dies, um unsere Ableitungsdefinitionen aufzubauen. In unserem Fall laden wir wahllos alle Artikelknoten und erstellen für jede von ihnen eine separate Definition, die sich nur durch eine andere Admin_Label unterscheidet (dies ist eine Eigenschaft in der DrupalcoreblockAnnotation -Annotationsklasse). Das Array der Derivate wird durch die ID des Ableitung gekleidet (in unserem Fall die Knoten -ID, die wir später verwenden werden).
Ein sehr wichtiger Punkt, den wir hier machen müssen, ist, dass das Laden aller Knoten und das Erstellen von Plugins aus ihnen niemals eine gute Idee ist. Was vielleicht interessant wäre, ist die Implementierung von Funktionen, durch die einzelne Knoten über ein Kontrollkästchen oder ähnliches als Blöcke freigelegt werden können.
Jetzt, da wir unsere Deriver -Klasse haben, erstellen wir ein einfaches Block -Plugin, mit dem es mehrere Instanzen von sich selbst generiert (einen für jeden Artikelknoten).
in SRC/Plugin/Block/NodeBlock.php:
<?php /** * @file * Contains \Drupal\demo\Plugin\Derivative\NodeBlock. */ namespace Drupal\demo\Plugin\Derivative; use Drupal\Component\Plugin\Derivative\DeriverBase; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides block plugin definitions for nodes. * * @see \Drupal\demo\Plugin\Block\NodeBlock */ class NodeBlock extends DeriverBase implements ContainerDeriverInterface { /** * The node storage. * * @var \Drupal\Core\Entity\EntityStorageInterface */ protected $nodeStorage; /** * Constructs new NodeBlock. * * @param \Drupal\Core\Entity\EntityStorageInterface $node_storage * The node storage. */ public function __construct(EntityStorageInterface $node_storage) { $this->nodeStorage = $node_storage; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, $base_plugin_id) { return new static( $container->get('entity.manager')->getStorage('node') ); } /** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { $nodes = $this->nodeStorage->loadByProperties(['type' => 'article']); foreach ($nodes as $node) { $this->derivatives[$node->id()] = $base_plugin_definition; $this->derivatives[$node->id()]['admin_label'] = t('Node block: ') . $node->label(); } return $this->derivatives; } }
Das erste, was wir in der Annotation dieses Plugins bemerken, ist der Ausleitungsschlüssel, der auf die zuvor erstellte Klasse hinweist. Und das ist im Grunde alles, was wir brauchen, um die beiden zu koppeln. Der abgeleitete Entdeckungsdekorator verarbeitet das schwere Heben.
Ein Großteil des Restes ist ein grundlegendes Blockgebäude, mit dem wir vertraut sein sollten. Interessant ist, dass wir mit der Methode GetderivativeId () die Knoten -ID abrufen können, die wir auch als ID der angezeigten Ableitung verwendet haben, und sie laden das Knotenobjekt und erstellen den Block als die tatsächliche Knotenausgabe. Zuletzt stellen wir in der BlockAccess () -Methode sicher, dass dieser Block die gleichen Zugriffsprüfungen wie der tatsächliche Knoten selbst hat. Wenn der aktuelle Benutzer keinen Zugriff auf den aktuellen Knoten hat, wird der Block nicht einmal angezeigt.
Wenn wir nun die Caches löschen und zur Block -Layout -Schnittstelle navigieren, sollten wir einige Blöcke bezeichnen, die als Knotenblock bezeichnet werden: [Knoten -Titel]. Sie können diese dort platzieren, wo Sie wollen, und sie werden den entsprechenden Knoten rendern.
In diesem Artikel haben wir uns Pluginderivate angesehen und ein einfaches Beispiel dafür gesehen, wie sie funktionieren. Der Schlüssel zu diesem Thema ist, dass Pluginderivate die Art und Weise sind, wie wir mehrere Instanzen desselben Plugins dynamisch deklarieren. Sie helfen uns normalerweise, die benutzerkonfigurierte Funktionalität (z. B. Menüs) in Plugins (z. B. Menüblöcke) zu verwandeln.
Um die Verwendung von Derivaten zu veranschaulichen, haben wir eine sehr einfache Technik gesehen, mit der wir Artikelknoten als Blöcke rendern können. Wir sollten uns daran erinnern, dies nicht auf einer Website mit vielen Artikelknoten auszuprobieren, sondern zusätzliche Funktionen zu implementieren, die die Anzahl der Knoten einschränkt, die ausgesetzt werden. Sie wissen, also stürzen wir unsere Website nicht ab.
Fragen? Kommentare? Gibt es etwas, das Sie gerne erklären möchten? Lass es uns wissen!
Das obige ist der detaillierte Inhalt vonTutorial über die Verwendung von Drupal 8 -Plugin -Derivaten effektiv. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!