WordPress自定义Bootstrap菜单开发求助:如何实现Products选项的下拉子菜单
Hey, I took a look at your code and the issue comes down to two main things: messed up logic for identifying parent menu items (like Products) and broken HTML nesting in your loop, which is why the dropdown isn't attaching to the right item. Let's fix this step by step.
Key Issues in Your Original Code
- You were using
order => DESCwhich reverses the menu order—parent items would show up after their children, breaking the hierarchy check - The dropdown structure was being triggered randomly instead of only when a parent item (like Products) has children
- HTML tags weren't being closed properly in the loop, leading to invalid markup that Bootstrap can't parse correctly
Corrected Full Code
Here's the revised version that will properly render the dropdown under your Products menu:
<?php $menu_name = 'main-menu'; // Replace with your menu slug or location $locations = get_nav_menu_locations(); $menu = wp_get_nav_menu_object( $menu_name ); $menuitems = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'ASC' ) ); // Use ASC to keep parent items first ?> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="container-fluid"> <button class='navbar-toggler' type='button' data-bs-toggle='collapse' data-bs-target='#navbarSupportedContent' aria-controls='navbarSupportedContent' aria-expanded='false' aria-label='Toggle navigation'> <span class='navbar-toggler-icon'></span> </button> <div class='collapse navbar-collapse' id='navbarSupportedContent'> <ul class='navbar-nav me-auto mb-2 mb-lg-0'> <?php $count = 0; $submenu_active = false; $current_parent_id = 0; foreach( $menuitems as $item ): $title = $item->title; $link = $item->url; $item_id = $item->ID; $parent_id = $item->menu_item_parent; // Handle top-level menu items (no parent) if ( $parent_id == 0 ): // Close any open submenu before starting a new top-level item if ( $submenu_active ): echo '</ul></li>'; $submenu_active = false; endif; // Check if this top-level item has children $has_children = false; foreach( $menuitems as $child ): if ( $child->menu_item_parent == $item_id ): $has_children = true; break; endif; endforeach; // Render dropdown if there are children (like Products) if ( $has_children ): $current_parent_id = $item_id; ?> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="<?php echo esc_url($link); ?>" role="button" data-bs-toggle="dropdown" aria-expanded="false"> <?php echo esc_html($title); ?> </a> <ul class="dropdown-menu"> <?php $submenu_active = true; else: // Render regular top-level item ?> <li class="nav-item"> <a class="nav-link" href="<?php echo esc_url($link); ?>"><?php echo esc_html($title); ?></a> </li> <?php endif; else: // Render child items only if they belong to the current parent if ( $parent_id == $current_parent_id && $submenu_active ): ?> <li><a class="dropdown-item" href="<?php echo esc_url($link); ?>"><?php echo esc_html($title); ?></a></li> <?php endif; endif; // Close the last submenu if we're at the end of the loop $count++; if ( $count == count($menuitems) && $submenu_active ): echo '</ul></li>'; endif; endforeach; ?> </ul> </div> </div> </nav>
What Changed & Why
- Menu Order: Switched to
order => ASCso parent items always come before their children—critical for hierarchy checks - Child Check: Added a loop to detect if a top-level item has children, so we only render the dropdown structure when needed (like for Products)
- Proper Nesting: Fixed HTML tag closing logic to ensure submenus are correctly wrapped under their parent items
- Security: Used
esc_url()andesc_html()to sanitize menu URLs and titles—best practice for WordPress development
Final Checks
- Make sure in your WordPress admin (
Appearance > Menus), you've dragged your submenu items under Products and indented them to set the parent-child relationship - Double-check that your theme loads Bootstrap's CSS and JavaScript (the dropdown won't toggle without the Bootstrap JS file)
内容的提问来源于stack exchange,提问作者Nizal Sha
相关产品推荐
相关产品推荐

