Dans Drupal, les éléments de menu sont gérés soit via l'interface d'administration soit dans les fichiers mon_module.links.menu.yml, de la manière suivante :
Un lien vers un noeud :
enfarandole.main.help:
title: 'Nous aider'
weight: 2
route_name: entity.node.canonical
route_parameters:
node: 5
menu_name: mainUn lien vers une vue :
amicale.main.events:
title: 'Évènements'
weight: 1
route_name: view.evenements.listing
menu_name: mainMais il est aussi possible d'utiliser un deriver, pour créer des éléments de menu de manière dynamique, dans l'exemple suivant je vais lister dans un sous menu tous les contenus d'un certains type, je commence par la déclaration de mon menu parent et de mon deriver, toujours dans le fichier mon_module.links.menu.yml :
# Mon élément parent, sans lien, qui sera dans le menu principal
amicale.main.sections:
title: 'Sections'
weight: 1
route_name: '<nolink>'
menu_name: main
# La définition de mon dériver pointant vers une classe
amicale.main.sections.section:
deriver: '\Drupal\mon_module\Plugin\Derivative\SectionMenuLinkDeriver'
class: '\Drupal\Core\Menu\MenuLinkDefault'La classe de mon dériver (web/modules/mon_module/src/Plugin/Derivative/SectionMenuLinkDeriver.php)
<?php
namespace Drupal\mon_module\Plugin\Derivative;
use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
use Drupal\Core\Url;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Menu deriver for content type « page_de_section ».
*/
final class SectionMenuLinkDeriver extends DeriverBase implements ContainerDeriverInterface {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManager
*/
protected EntityTypeManager $entityTypeManager;
/**
* CategoryMenuLinkDeriver constructor.
*
* @param \Drupal\Core\Entity\EntityTypeManager $entityTypeManager
* The entity type manager.
*/
public function __construct(EntityTypeManager $entityTypeManager) {
$this->entityTypeManager = $entityTypeManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, $base_plugin_id) {
return new static($container->get('entity_type.manager'));
}
/**
* {@inheritdoc}
*/
public function getDerivativeDefinitions($base_plugin_definition) {
$links = [];
$storage = $this->entityTypeManager->getStorage('node');
$query = $storage->getQuery();
// Je charge tous les noeud du type « page_de_section »
$query->accessCheck(TRUE);
$query->condition('type', 'page_de_section');
$query->sort('title');
$sections = $query->execute();
// Et pour chaque, je vais créer un élément de menu
foreach ($sections as $section) {
if (!$section = $storage->load($section)) {
continue;
}
// Create menu ID.
$menuId = 'amicale.main.sections.section:' . $section->id();
$link = [
'id' => $menuId,
'route_name' => entity.node.canonical,
'route_parameters' => ['node' => $section->id()],
'title' => $section->label(), // Le titre de mon élément de menu (ici le titre du noeud)
'parent' => 'amicale.main.sections', // je définis ici le menu item parent, si omis, ça sera un élément de menu de niveau 1
] + $base_plugin_definition;
$links[$menuId] = $link;
}
return $links;
}
}
On vide son cache, et voila !
Évidement tout est possible au niveau de ce que l'on veut ajouter comme élément de menu, catégories basée sur un vocabulaire, liste de membres...
Commentaires (0)