9.6. Route mit Parameter.
Wir können Parameter in der URL für Routen verwenden. Sie funktionieren genau wie kontextbezogene Filter in Views. Wir können beispielsweise die ID verschiedener Entitäten, Textzeichenfolgen oder eine sequentielle ID, getrennt durch Kommas oder Pluszeichen, in der URL übergeben. In dieser Lektion übergeben wir die ID des Knotens und zeigen den Titel und den Inhalt dieses Knotens auf der Seite an.
Beispiele für den Code finden Sie auf GitHub:
https://github.com/levmyshkin/drupalbook8
Fügen wir eine Route zu unserer Datei drupalbook.routing.yml im Modul hinzu:
drupalbook.display_node:
path: '/display-node/{node}'
defaults:
_controller: '\Drupal\drupalbook\Controller\DisplayNode::content'
_title_callback: '\Drupal\drupalbook\Controller\DisplayNode::getTitle'
requirements:
_custom_access: '\Drupal\drupalbook\Controller\DisplayNode::access'
options:
parameters:
node:
type: entity:node
Hier übergeben wir im Pfad als zweiten Parameter {node}
. In der URL schreiben wir die übliche ID, z. B. /display-node/101, aber ein fertiges Node-Objekt wird an unseren Controller übergeben. Dazu geben wir in options
die Parameter an, was übergeben wird und was das Ergebnis sein wird:
options:
parameters:
node: # Name des Arguments, das in {} steht, es kann auch node1, node2 sein, wenn wir zwei verschiedene Argumente übergeben.
type: entity:node # Was als Ausgabe übergeben wird, wir können im Controller mit diesem Entity-Objekt arbeiten.
Außerdem geben wir mit _title_callback
an, in welcher Methode der Titel angezeigt wird. Und wir beschränken die Ausgabe von Artikeln auf anonyme Benutzer, dazu verwenden wir den Parameter _custom_access
, in dem wir angeben, in welcher Methode verschiedene Zugriffsrestriktionen angewandt werden.
Nachdem wir die Route beschrieben haben, schreiben wir die Klasse für diese Route.
Datei modules/custom/drupalbook/src/Controller/DisplayNode.php
:
<?php
/**
* @file
* Enthält \Drupal\drupalbook\Controller\DisplayNode.
*/
namespace Drupal\drupalbook\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\node\NodeInterface;
/**
* Bietet Routen-Antworten für das DrupalBook-Modul.
*/
class DisplayNode {
/**
* Gibt eine einfache Seite zurück.
*
* @return array
* Ein einfaches renderbares Array.
*/
public function content(NodeInterface $node) {
$element = array(
'#markup' => $node->body->value,
);
return $element;
}
/**
* Prüft den Zugriff für diesen Controller.
*/
public function access(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
/**
* Gibt den Seitentitel zurück.
*/
public function getTitle(NodeInterface $node) {
return $node->getTitle();
}
}
Ich habe eine separate Klasse für die Route erstellt, damit wir nicht alles in einem Controller mischen. Schauen wir uns an, was jede Zeile bedeutet:
\drupalbook\Controller;
Hier geben wir an, wo unsere Controller-Datei liegt.
\Core\Access\AccessResult;
use Drupal\node\NodeInterface;
Wir binden die Klasse AccessResult ein, um z. B. den Fehler 403 auszugeben, und NodeInterface, um das Node-Objekt als Parameter in den Controller-Methoden zu erhalten.
function content(NodeInterface $node) {
$element = array(
'#markup' => $node->body->value,
);
return $element;
}
Beachten Sie hier den Parameter: Wir erhalten das Node-Objekt. Drupal wandelt automatisch die ID aus der URL in ein Objekt um und übergibt es uns, sodass wir das Node-Objekt nicht selbst laden müssen. $node->body->value
ist der Wert des Feldes im Node. Am Ende geben wir ein Render-Array mit #markup
zurück, um den Inhalt der Node-Seite auszugeben.
function access(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
Wir verwenden die Methode currentUser()
, um den aktuellen Benutzer zu bekommen, und holen dann dessen Rollen. Im if
-Check prüfen wir den Inhaltstyp und die Benutzerrolle. Anonyme Nutzer erhalten eine 403-Fehlerseite, alle anderen haben Zugriff. Mit AccessResult
können wir flexibel Zugriffsrechte steuern.
Die Klasse AccessResult
bietet Methoden wie:
neutral allowed forbidden allowedIf forbiddenIf allowedIfHasPermission allowedIfHasPermissions isAllowed isForbidden isNeutral orIf andIf
Sie können z.B. allowedIfHasPermission()
verwenden, um Zugriffsrechte anhand von Berechtigungen zu differenzieren. Alternativ legen Sie Rechte auch über die YAML-Datei der Route fest. Die Klasse bietet aber mehr Flexibilität, z. B. zeitlich oder rollenbasiert differenzierte Zugriffslogiken.
function getTitle(NodeInterface $node) {
return $node->getTitle();
}
Hier geben wir einfach den Titel der Node als Seitenüberschrift zurück. Sie können die Methode beliebig erweitern, z. B. so:
function getTitle(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return 'Premium content: ' . $node->getTitle();
}
else {
return 'Free access content: ' . $node->getTitle();
}
}
Oder das Veröffentlichungsdatum in den Titel einfügen.
Wie Sie sehen, bietet Drupal viele Möglichkeiten, Routen und Controller flexibel zu konfigurieren. So können Sie Kundenwünsche für die Ausgabe von Inhalten einfach mit der Drupal API und etwas PHP-Code umsetzen.
Beispiele finden Sie auf GitHub:
https://github.com/levmyshkin/drupalbook8