diff --git a/core/lib/Drupal/Core/Menu/MenuLinkTree.php b/core/lib/Drupal/Core/Menu/MenuLinkTree.php index 090293c..6307c49 100644 --- a/core/lib/Drupal/Core/Menu/MenuLinkTree.php +++ b/core/lib/Drupal/Core/Menu/MenuLinkTree.php @@ -243,26 +243,28 @@ protected function buildItems(array $tree, CacheableMetadata &$tree_access_cache if ($data->access instanceof AccessResultInterface && !$data->access->isAllowed()) { continue; } + $element = []; - $class = ['menu-item']; - // Set a class for the
  • -tag. Only set 'expanded' class if the link - // also has visible children within the current tree. + // Set a variable for the
  • tag. Only set 'expanded' to true if the + // link also has visible children within the current tree. + $element['is_expanded'] = FALSE; + $element['is_collapsed'] = FALSE; if ($data->hasChildren && !empty($data->subtree)) { - $class[] = 'menu-item--expanded'; + $element['is_expanded'] = TRUE; } elseif ($data->hasChildren) { - $class[] = 'menu-item--collapsed'; + $element['is_collapsed'] = TRUE; } - // Set a class if the link is in the active trail. + // Set a helper variable to indicate whether the link is in the active + // trail. + $element['in_active_trail'] = FALSE; if ($data->inActiveTrail) { - $class[] = 'menu-item--active-trail'; + $element['in_active_trail'] = TRUE; } // Note: links are rendered in the menu.html.twig template; and they // automatically bubble their associated cacheability metadata. - $element = array(); $element['attributes'] = new Attribute(); - $element['attributes']['class'] = $class; $element['title'] = $link->getTitle(); $element['url'] = $link->getUrlObject(); $element['url']->setOption('set_active_class', TRUE); diff --git a/core/modules/book/src/BookManager.php b/core/modules/book/src/BookManager.php index fcb46a4..e6e2588 100644 --- a/core/modules/book/src/BookManager.php +++ b/core/modules/book/src/BookManager.php @@ -539,30 +539,33 @@ protected function buildItems(array $tree) { $items = []; foreach ($tree as $data) { - $class = ['menu-item']; + $element = []; + // Generally we only deal with visible links, but just in case. if (!$data['link']['access']) { continue; } - // Set a class for the
  • -tag. Since $data['below'] may contain local - // tasks, only set 'expanded' class if the link also has children within + // Set a class for the
  • tag. Since $data['below'] may contain local + // tasks, only set 'expanded' to true if the link also has children within // the current book. + $element['is_expanded'] = FALSE; + $element['is_collapsed'] = FALSE; if ($data['link']['has_children'] && $data['below']) { - $class[] = 'menu-item--expanded'; + $element['is_expanded'] = TRUE; } elseif ($data['link']['has_children']) { - $class[] = 'menu-item--collapsed'; + $element['is_collapsed'] = TRUE; } - // Set a class if the link is in the active trail. + // Set a helper variable to indicate whether the link is in the active + // trail. + $element['in_active_trail'] = FALSE; if ($data['link']['in_active_trail']) { - $class[] = 'menu-item--active-trail'; + $element['in_active_trail'] = TRUE; } // Allow book-specific theme overrides. - $element = []; $element['attributes'] = new Attribute(); - $element['attributes']['class'] = $class; $element['title'] = $data['link']['title']; $node = $this->entityManager->getStorage('node')->load($data['link']['nid']); $element['url'] = $node->urlInfo(); diff --git a/core/modules/book/templates/book-tree.html.twig b/core/modules/book/templates/book-tree.html.twig index a4edb37..bf7424f 100644 --- a/core/modules/book/templates/book-tree.html.twig +++ b/core/modules/book/templates/book-tree.html.twig @@ -11,6 +11,11 @@ * - below: The book item child items. * - title: The book link title. * - url: The book link URL, instance of \Drupal\Core\Url. + * - is_expanded: TRUE if the link has visible children within the current + * book tree. + * - is_collapsed: TRUE if the link has children within the current book tree + * that are not currently visible. + * - in_active_trail: TRUE if the link is in the active trail. * * @ingroup themeable */ @@ -31,14 +36,14 @@ {% else %} {% endif %} {% endmacro %} diff --git a/core/modules/system/templates/menu.html.twig b/core/modules/system/templates/menu.html.twig index a9c7899..03704f2 100644 --- a/core/modules/system/templates/menu.html.twig +++ b/core/modules/system/templates/menu.html.twig @@ -11,6 +11,11 @@ * - title: The menu link title. * - url: The menu link url, instance of \Drupal\Core\Url * - localized_options: Menu link localized options. + * - is_expanded: TRUE if the link has visible children within the current + * menu tree. + * - is_collapsed: TRUE if the link has children within the current menu tree + * that are not currently visible. + * - in_active_trail: TRUE if the link is in the active trail. * * @ingroup themeable */ @@ -31,14 +36,14 @@ {% else %} {% endif %} {% endmacro %} diff --git a/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php b/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php index da545b2..9faa03d 100644 --- a/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php +++ b/core/modules/system/tests/src/Unit/Menu/MenuLinkTreeTest.php @@ -140,14 +140,29 @@ public function providerTestBuildCacheability() { ] ]; - $get_built_element = function(MenuLinkTreeElement $element, array $classes) { - return [ - 'attributes' => new Attribute(['class' => array_merge(['menu-item'], $classes)]), + $get_built_element = function(MenuLinkTreeElement $element) { + $return = [ + 'attributes' => new Attribute(), 'title' => $element->link->getTitle(), 'url' => new Url($element->link->getRouteName(), $element->link->getRouteParameters(), ['set_active_class' => TRUE]), 'below' => [], 'original_link' => $element->link, + 'is_expanded' => FALSE, + 'is_collapsed' => FALSE, + 'in_active_trail' => FALSE, ]; + + if ($element->hasChildren && !empty($element->subtree)) { + $return['is_expanded'] = TRUE; + } + elseif ($element->hasChildren) { + $return['is_collapsed'] = TRUE; + } + if ($element->inActiveTrail) { + $return['in_active_trail'] = TRUE; + } + + return $return; }; // The three access scenarios described in this method's documentation. @@ -195,7 +210,7 @@ public function providerTestBuildCacheability() { $tree[0]->access = $access; if ($access === NULL || $access->isAllowed()) { $expected_build = $base_expected_build; - $expected_build['#items']['test.example1'] = $get_built_element($tree[0], []); + $expected_build['#items']['test.example1'] = $get_built_element($tree[0]); } else { $expected_build = $base_expected_build_empty; @@ -217,9 +232,9 @@ public function providerTestBuildCacheability() { $tree[0]->access = $access; $expected_build = $base_expected_build; if ($access === NULL || $access->isAllowed()) { - $expected_build['#items']['test.example1'] = $get_built_element($tree[0], []); + $expected_build['#items']['test.example1'] = $get_built_element($tree[0]); } - $expected_build['#items']['test.example2'] = $get_built_element($tree[1], []); + $expected_build['#items']['test.example2'] = $get_built_element($tree[1]); $expected_build['#cache']['contexts'] = array_merge($expected_build['#cache']['contexts'], $access_cache_contexts, $links[0]->getCacheContexts(), $links[1]->getCacheContexts()); $data[] = [ 'description' => "Single-level tree; access=$i; link=$j.", @@ -245,13 +260,13 @@ public function providerTestBuildCacheability() { ]; $tree[0]->subtree[0]->subtree[0]->access = $access; $expected_build = $base_expected_build; - $expected_build['#items']['test.roota'] = $get_built_element($tree[0], ['menu-item--expanded']); - $expected_build['#items']['test.roota']['below']['test.parentc'] = $get_built_element($tree[0]->subtree[0], ['menu-item--expanded']); + $expected_build['#items']['test.roota'] = $get_built_element($tree[0]); + $expected_build['#items']['test.roota']['below']['test.parentc'] = $get_built_element($tree[0]->subtree[0]); if ($access === NULL || $access->isAllowed()) { - $expected_build['#items']['test.roota']['below']['test.parentc']['below']['test.example1'] = $get_built_element($tree[0]->subtree[0]->subtree[0], []); + $expected_build['#items']['test.roota']['below']['test.parentc']['below']['test.example1'] = $get_built_element($tree[0]->subtree[0]->subtree[0]); } - $expected_build['#items']['test.rootb'] = $get_built_element($tree[1], ['menu-item--expanded']); - $expected_build['#items']['test.rootb']['below']['test.example2'] = $get_built_element($tree[1]->subtree[0], []); + $expected_build['#items']['test.rootb'] = $get_built_element($tree[1]); + $expected_build['#items']['test.rootb']['below']['test.example2'] = $get_built_element($tree[1]->subtree[0]); $expected_build['#cache']['contexts'] = array_merge($expected_build['#cache']['contexts'], $access_cache_contexts, $links[0]->getCacheContexts(), $links[1]->getCacheContexts()); $data[] = [ 'description' => "Multi-level tree; access=$i; link=$j.", diff --git a/core/modules/toolbar/templates/menu--toolbar.html.twig b/core/modules/toolbar/templates/menu--toolbar.html.twig index 3578b95..659e8f5 100644 --- a/core/modules/toolbar/templates/menu--toolbar.html.twig +++ b/core/modules/toolbar/templates/menu--toolbar.html.twig @@ -11,6 +11,11 @@ * - title: The menu link title. * - url: The menu link url, instance of \Drupal\Core\Url * - localized_options: Menu link localized options. + * - is_expanded: TRUE if the link has visible children within the current + * menu tree. + * - is_collapsed: TRUE if the link has children within the current menu tree + * that are not currently visible. + * - in_active_trail: TRUE if the link is in the active trail. * * @ingroup themeable */ @@ -31,14 +36,22 @@ {% else %} {% endif %} {% endmacro %} diff --git a/core/themes/classy/templates/navigation/book-tree.html.twig b/core/themes/classy/templates/navigation/book-tree.html.twig index 543696c..186a547 100644 --- a/core/themes/classy/templates/navigation/book-tree.html.twig +++ b/core/themes/classy/templates/navigation/book-tree.html.twig @@ -11,6 +11,11 @@ * - below: The book item child items. * - title: The book link title. * - url: The book link URL, instance of \Drupal\Core\Url. + * - is_expanded: TRUE if the link has visible children within the current + * book tree. + * - is_collapsed: TRUE if the link has children within the current book tree + * that are not currently visible. + * - in_active_trail: TRUE if the link is in the active trail. */ #} {% import _self as book_tree %} @@ -29,14 +34,22 @@ {% else %} {% endif %} {% endmacro %} diff --git a/core/themes/classy/templates/navigation/menu.html.twig b/core/themes/classy/templates/navigation/menu.html.twig index 4e12ea1..67ada7d 100644 --- a/core/themes/classy/templates/navigation/menu.html.twig +++ b/core/themes/classy/templates/navigation/menu.html.twig @@ -11,6 +11,11 @@ * - title: The menu link title. * - url: The menu link url, instance of \Drupal\Core\Url * - localized_options: Menu link localized options. + * - is_expanded: TRUE if the link has visible children within the current + * tree. + * - is_collapsed: TRUE if the link has children within the current tree that + * are not currently visible. + * - in_active_trail: TRUE if the link is in the active trail. */ #} {% import _self as menus %} @@ -29,14 +34,22 @@ {% else %} {% endif %} {% endmacro %}