9.6. Rotta con parametro.
Possiamo utilizzare i parametri nell'URL per le rotte. Funzionano proprio come i filtri contestuali nelle Views. Possiamo, ad esempio, passare nell'URL l'ID di varie entità, stringhe di testo o ID sequenziali separati da virgola o più. In questa lezione, passeremo l'ID del nodo e mostreremo il titolo e il corpo di questo nodo nel contenuto.
Esempi di codice possono essere visualizzati su github:
https://github.com/levmyshkin/drupalbook8
Aggiungiamo la rotta al nostro file drupalbook.routing.yml del modulo:
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
Qui nel path passiamo come secondo argomento {node}, nell'URL scriveremo l'ID normale: /display-node/101, ma un oggetto nodo predefinito arriverà al nostro controller. Per fare ciò, indichiamo nelle opzioni i parametri che devono essere passati a questi parametri e quale sarà l'output.
options:
parameters:
node: # il nome dell'argomento, ciò che è tra {}, può essere node1, node2, se passiamo due argomenti diversi.
type: entity:node # ciò che sarà l'output, possiamo usare l'oggetto di questa entità all'interno del controller.
Ho anche determinato in quale metodo mostreremo l'intestazione usando il parametro _title_callback. E limiteremo l'output degli articoli agli utenti anonimi, per fare questo usiamo il parametro _custom_access in cui indichiamo in quale metodo imporremo varie restrizioni.
Ora, una volta compreso il funzionamento della rotta, passiamo alla scrittura di una classe per questa rotta.
modules/custom/drupalbook/src/Controller/DisplayNode.php:
<?php
/**
* @file
* Contains \Drupal\drupalbook\Controller\DisplayNode.
*/
namespace Drupal\drupalbook\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\node\NodeInterface;
/**
* Provides route responses for the DrupalBook module.
*/
class DisplayNode {
/**
* Returns a simple page.
*
* @return array
* A simple renderable array.
*/
public function content(NodeInterface $node) {
$element = array(
'#markup' => $node->body->value,
);
return $element;
}
/**
* Checks access for this controller.
*/
public function access(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
/**
* Returns a page title.
*/
public function getTitle(NodeInterface $node) {
return $node->getTitle();
}
}
Ho creato una classe separata per la mia rotta, in modo da non mescolare tutto in un'unica classe controller. Vediamo cosa significa ciascuna di queste righe.
\drupalbook\Controller;
Indichiamo dove si trova il nostro file controller.
\Core\Access\AccessResult;
use Drupal\node\NodeInterface;
Includiamo i file delle classi AccessResult - lo useremo per generare l'errore 403 e NodeInterface - lo useremo per ottenere l'oggetto nodo nel metodo dei parametri del nostro controller.
function content(NodeInterface $node) {
$element = array(
'#markup' => $node->body->value,
);
return $element;
}
Qui, fai attenzione al parametro, otteniamo l'oggetto nodo, Drupal stesso converte l'ID dall'URL e ce lo passa, così non dobbiamo ricaricare l'oggetto nodo ma ottenerlo già pronto dove ne abbiamo bisogno. $node->body->value, questo è come otteniamo il valore del campo dal nodo, ma ci occuperemo della gestione degli oggetti nei dettagli nella lezione successiva quando analizzeremo l'Entity API. Alla fine, restituiamo un array con #markup per visualizzare il nostro nodo nella pagina di testo.
function access(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
Prima usiamo il metodo Drupal currentUser() per ottenere l'oggetto utente corrente, quindi useremo questo oggetto per ottenere i ruoli dell'utente corrente. Nel controllo if, verifichiamo il tipo di contenuto del nostro nodo e il ruolo dell'utente, gli utenti anonimi riceveranno un errore 403, se tutto va bene, procediamo e restituiamo allowed(), cioè approviamo semplicemente il nostro controllo. Apriamo la classe AccessResult e vediamo quali altri metodi ha questa classe. Per farlo, in PhpStorm devi premere due volte shift e inserire il nome della classe:
Qui puoi trovare i seguenti metodi per il controllo dei permessi:
neutral allowed forbidden allowedIf forbiddenIf allowedIfHasPermission allowedIfHasPermissions isAllowed isForbidden isNeutral orIf andIf
Puoi sperimentare con allowedIfHasPermission(), ad esempio, e impostare permessi diversi per i diversi ruoli della tua rotta. Ad esempio, crea una nuova autorizzazione nel tuo modulo e usala nel controller. Anche se è più semplice, naturalmente, usare i permessi nel file yml della rotta. Ma attraverso la classe AccessResult, puoi descrivere in modo flessibile la logica per l'accesso ai contenuti, ad esempio "l'accesso al contenuto è consentito agli utenti autorizzati dalle 12 alle 16 ore, e per gli utenti con il ruolo di account premium tutto il giorno". Sperimenta e implementa questa differenziazione dei diritti di accesso ai nodi articolo.
Come puoi vedere, Drupal fornisce diversi modi per implementare l'accesso ai contenuti, il che è comodo perché il 99% dei casi utilizza un solo permesso ed è sufficiente per differenziare i diritti di accesso.
function getTitle(NodeInterface $node) {
return $node->getTitle();
}
Qui restituiamo semplicemente il nome del nodo come titolo, ma possiamo espandere le funzionalità del nostro callback. Ad esempio, così:
function getTitle(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return 'Contenuto Premium: ' . $node->getTitle();
}
else {
return 'Contenuto accessibile gratuitamente: ' . $node->getTitle();
}
}
Oppure visualizzare la data di pubblicazione nel titolo:
Come puoi vedere, Drupal offre la possibilità di configurare in modo flessibile la tua rotta e controller. Quindi, quando il tuo cliente avrà delle idee sulla visualizzazione dei materiali sul sito, potrai sempre farlo utilizzando l'API di Drupal e un po' di codice PHP.
Esempi di codice possono essere visualizzati su github:
https://github.com/levmyshkin/drupalbook8