9.6. Ruta con parámetro.
Podemos usar parámetros en la URL para las rutas. Funcionan igual que los filtros contextuales en Views. Por ejemplo, podemos pasar en la URL el ID de varias entidades, cadenas de texto o identificadores secuenciales separados por comas o signos más. En esta lección, pasaremos el ID del nodo y mostraremos el título y el cuerpo de este nodo en el contenido.
Ejemplos de código disponibles en github:
https://github.com/levmyshkin/drupalbook8
Agreguemos una ruta en el archivo drupalbook.routing.yml de nuestro módulo:
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
Aquí en path pasamos como segundo argumento {node}, en la URL escribiremos el ID como de costumbre: /display-node/101, pero en nuestro controlador recibiremos el objeto de nodo ya cargado. Para eso, indicamos en options los parámetros que deben ser procesados y su tipo de salida.
options:
parameters:
node:
type: entity:node
También definimos el método que mostrará el encabezado con _title_callback. Y limitamos el acceso de usuarios anónimos a los artículos usando el parámetro _custom_access que llama a un método de restricción personalizada.
Ahora que entendemos la ruta, escribamos la clase correspondiente.
modules/custom/drupalbook/src/Controller/DisplayNode.php:
<?php
namespace Drupal\drupalbook\Controller;
use Drupal\Core\Access\AccessResult;
use Drupal\node\NodeInterface;
class DisplayNode {
public function content(NodeInterface $node) {
$element = array(
'#markup' => $node->body->value,
);
return $element;
}
public function access(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return AccessResult::forbidden();
}
return AccessResult::allowed();
}
public function getTitle(NodeInterface $node) {
return $node->getTitle();
}
}
Usamos la clase AccessResult para devolver 403 si es necesario, y NodeInterface para que Drupal convierta automáticamente el ID de la URL en un objeto nodo.
En el método content() usamos $node->body->value
para obtener el contenido del campo body y devolverlo con #markup.
En access() usamos \Drupal::currentUser()
para obtener el usuario actual, luego comprobamos si el tipo de contenido del nodo es "article" y si el usuario no tiene el rol "authenticated". Si se cumple, denegamos el acceso.
En getTitle() devolvemos el título del nodo. Podemos ampliarlo, por ejemplo:
function getTitle(NodeInterface $node) {
$user = \Drupal::currentUser();
if ($node->getType() == 'article' && !in_array('authenticated', $user->getRoles())) {
return 'Contenido Premium: ' . $node->getTitle();
}
else {
return 'Contenido de libre acceso: ' . $node->getTitle();
}
}
También se puede mostrar la fecha de publicación en el título.
Como ves, Drupal permite configurar rutas y controladores con gran flexibilidad. Así que cuando tu cliente tenga ideas sobre cómo mostrar contenido, podrás implementarlas con la API de Drupal y un poco de código PHP.
Ejemplos de código disponibles en github:
https://github.com/levmyshkin/drupalbook8