Drupal 8 - Définir l'item de menu actif en fonction du type de noeud

Posté le Mercredi 20 septembre 2017 - 17:48
Dernière mise à jour le Vendredi 17 novembre 2017 - 17:04

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).

Par défaut quand on est sur la vue de listing des snippets par exemple, on a bien l'élément de menu "Snippets" qui est marqué comme actif, par contre quand on va sur le détail d'un snippet, on perd cette information. Nous allons voir comment sélectionner le menu item qui doit être actif en fonction du type de contenu sur lequel on se trouve.

1ère étape : surcharger le service MenuActiveTrail

dans mon module « kgaut » je créé le fichier KgautMenuActiveTrail.php dans le dossier src/Menu avec le contenu suivant :

  1. <?php
  2.  
  3. namespace Drupal\kgaut\Menu;
  4.  
  5. use Drupal\Core\Menu\MenuActiveTrail;
  6. use Drupal\node\NodeInterface;
  7.  
  8. /**
  9.  * Extend the MenuActiveTrail class.
  10.  */
  11. class KgautMenuActiveTrail extends MenuActiveTrail {
  12.  
  13. /**
  14.   * {@inheritdoc}
  15.   */
  16. public function getActiveLink($menu_name = NULL) {
  17. // Call the parent method to implement the default behavior.
  18. $found = parent::getActiveLink($menu_name);
  19.  
  20. // If a node is displayed, load the default parent menu item
  21. // from the node type's menu settings and return it instead
  22. // of the default one.
  23. $node = $this->routeMatch->getParameter('node');
  24.  
  25. if ($node instanceof NodeInterface) {
  26. $bundle = $node->bundle();
  27. switch ($bundle) {
  28. case 'article':
  29. //Ici je demande à recherche le menu item qui utilise la route correspondant à mon type de contenu
  30. $links = $this->menuLinkManager->loadLinksByRoute('view.front_articles.page', [], $menu_name);
  31. break;
  32.  
  33. case 'snippet':
  34. $links = $this->menuLinkManager->loadLinksByRoute('view.front_snippets.page', [], $menu_name);
  35. break;
  36.  
  37. case 'realisation':
  38. $links = $this->menuLinkManager->loadLinksByRoute('view.front_realisations.page', [], $menu_name);
  39. break;
  40. }
  41.  
  42. if (isset($links) && $links) {
  43. $found = reset($links);
  44. }
  45. }
  46. return $found;
  47. }
  48. }

C'est bien beau, mais maintenant il faut signaler à Drupal que l'on a surchargé un de ses services. Pour cela il faut créer le fichier src/MonModuleServiceProvider.php (attention c'est normé !) Dans mon cas j'ai donc créé le fichier KgautServiceProvider.php dans le dossier src de mon module kgaut (oui je suis très égocentrique).
En voici le contenu :

  1. <?php
  2. /**
  3.  * @file
  4.  * Contains Drupal\kgaut\KgautServiceProvider.
  5.  */
  6.  
  7. namespace Drupal\kgaut;
  8.  
  9. use Drupal\Core\DependencyInjection\ContainerBuilder;
  10. use Drupal\Core\DependencyInjection\ServiceProviderBase;
  11.  
  12. class KgautServiceProvider extends ServiceProviderBase {
  13.  
  14. /**
  15.   * {@inheritdoc}
  16.   */
  17. public function alter(ContainerBuilder $container) {
  18. $container->getDefinition('menu.active_trail')->setClass('Drupal\kgaut\Menu\KgautMenuActiveTrail');
  19. }
  20.  
  21. }

Un petit vidage de cache plus tard, et on est bon !

 

Ajouter un commentaire

Ne sera pas publié

HTML restreint

  • Balises HTML autorisées : <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Les lignes et les paragraphes vont à la ligne automatiquement.
  • Les adresses de pages web et les adresses courriel se transforment en liens automatiquement.
CAPTCHA
Désolé, pour ça, mais c'est le seul moyen pour éviter le spam...