Skip to content

Commit

Permalink
Menus: Apply menu-item-has-children class in sub-menus.
Browse files Browse the repository at this point in the history
Ensure the `menu-item-has-children` class is added to sub-menu items when `wp_nav_menu()` is called with the `depth` parameter specified to a non-zero value.

Follow up to [54478].

Props davidvongries, fpodhorsky, hellofromTonya, innovext, larsmqller, LeonidasMilossis, mattkeys, mukesh27, nuvoPoint, ocean90, outrankjames, petitphp, SergeyBiryukov, sippis, webmandesign.
Fixes #56946.
See #28620.


git-svn-id: https://develop.svn.wordpress.org/trunk@54801 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
peterwilsoncc committed Nov 11, 2022
1 parent 8368eef commit ac84f67
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 14 deletions.
14 changes: 7 additions & 7 deletions src/wp-includes/nav-menu-template.php
Expand Up @@ -204,14 +204,14 @@ function wp_nav_menu( $args = array() ) {
if ( $menu_item->menu_item_parent ) {
$menu_items_with_children[ $menu_item->menu_item_parent ] = 1;
}
}

// Calculate the depth of each menu item with children
foreach ( $menu_items_with_children as $menu_item_key => &$menu_item_depth ) {
$menu_item_parent = $menu_items_tree[ $menu_item_key ];
while ( $menu_item_parent ) {
$menu_item_depth = $menu_item_depth + 1;
$menu_item_parent = $menu_items_tree[ $menu_item_parent ];
}
// Calculate the depth of each menu item with children.
foreach ( $menu_items_with_children as $menu_item_key => &$menu_item_depth ) {
$menu_item_parent = $menu_items_tree[ $menu_item_key ];
while ( $menu_item_parent ) {
$menu_item_depth = $menu_item_depth + 1;
$menu_item_parent = $menu_items_tree[ $menu_item_parent ];
}
}

Expand Down
47 changes: 40 additions & 7 deletions tests/phpunit/tests/menu/wp-nav-menu.php
Expand Up @@ -11,6 +11,7 @@ class Tests_Menu_wpNavMenu extends WP_UnitTestCase {
static $lvl0_menu_item = 0;
static $lvl1_menu_item = 0;
static $lvl2_menu_item = 0;
static $lvl3_menu_item = 0;

public static function set_up_before_class() {
parent::set_up_before_class();
Expand Down Expand Up @@ -53,6 +54,18 @@ public static function set_up_before_class() {
)
);

// Create lvl3 menu item.
self::$lvl3_menu_item = wp_update_nav_menu_item(
self::$menu_id,
0,
array(
'menu-item-title' => 'Lvl3 menu item',
'menu-item-url' => '#',
'menu-item-parent-id' => self::$lvl2_menu_item,
'menu-item-status' => 'publish',
)
);

/*
* This filter is used to prevent reusing a menu item ID more that once.
* It caused the tests to fail after the first one since the IDs are missing
Expand Down Expand Up @@ -81,6 +94,7 @@ public static function tear_down_after_class() {
* when displaying the menu without specifying a custom depth.
*
* @ticket 28620
* @ticket 56946
*/
public function test_wp_nav_menu_should_have_has_children_class_without_custom_depth() {

Expand Down Expand Up @@ -112,11 +126,20 @@ public function test_wp_nav_menu_should_have_has_children_class_without_custom_d

$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-%1$d">',
self::$lvl2_menu_item
),
$menu_html,
'Level 2 should be present in the HTML output and not have the `menu-item-has-children` class since it has no children.'
'Level 2 should be present in the HTML output and have the `menu-item-has-children` class.'
);

$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
self::$lvl3_menu_item
),
$menu_html,
'Level 3 should be present in the HTML output and not have the `menu-item-has-children` class since it has no children.'
);
}

Expand All @@ -125,14 +148,15 @@ public function test_wp_nav_menu_should_have_has_children_class_without_custom_d
* `menu-item-has-children` even if it's the case when displaying the full menu.
*
* @ticket 28620
* @ticket 56946
*/
public function test_wp_nav_menu_should_not_have_has_children_class_with_custom_depth() {

// Render the menu limited to 1 level of hierarchy (Lvl0 + Lvl1).
$menu_html = wp_nav_menu(
array(
'menu' => self::$menu_id,
'depth' => 2,
'depth' => 3,
'echo' => false,
)
);
Expand All @@ -148,20 +172,29 @@ public function test_wp_nav_menu_should_not_have_has_children_class_with_custom_

$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-%1$d">',
self::$lvl1_menu_item
),
$menu_html,
'Level 1 should be present in the HTML output and not have the `menu-item-has-children` class since it is the last item to be rendered.'
'Level 1 should be present in the HTML output and have the `menu-item-has-children` class.'
);

$this->assertStringContainsString(
sprintf(
'<li id="menu-item-%1$d" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-%1$d">',
self::$lvl2_menu_item
),
$menu_html,
'Level 2 should be present in the HTML output and not have the `menu-item-has-children` class since it is the last item to be rendered.'
);

$this->assertStringNotContainsString(
sprintf(
'<li id="menu-item-%d"',
self::$lvl2_menu_item
self::$lvl3_menu_item
),
$menu_html,
'Level 2 should not be present in the HTML output.'
'Level 3 should not be present in the HTML output.'
);
}
}

0 comments on commit ac84f67

Please sign in to comment.