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...
Contenus en rapport
Sur ce site, j'ai trois types de contenu :
- Article
- Snippet
- Réalisation
Pour chacun de ces trois types de contenu, j'ai une vue (View) de listing qui correspond (cf le menu ci-dessus).
Voici comment créer un Menu item (élément de menu) avec des paramètres GET.
Voici comment ajouter une classe css à un élément de menu défini dans un module.
mon_module.links.menu.yml
Note : Il est aussi possible de créer des éléments de menu dans le fichier MODULE.links.menu.yml, cf : https://kgaut.net/snippets/2017/drupal-8-creer-un-element-de-menu-vers-… et
Dans le contrôleur / Bloc...
Ajouter un commentaire