admin管理员组

文章数量:1122846

I am using the WP_bootstrap_navwalker for a dropdown menu that opens to the side . This works fine, but it only shows me the first and second level items, i want it to show the third and fourth level.

Each level of the menu is inside a column, so the first and teh second are good, the third appears but under the second level instead of on the next column and the fourth level does not even open.

It´s the first time i´m using a nav_walker, can anyone help me?

The walker code:

class bootstrap_5_wp_nav_menu_walker extends Walker_Nav_menu{
private $current_item;
private $dropdown_menu_alignment_values = [
    'dropdown-menu-start',
    'dropdown-menu-end',
    'dropdown-menu-sm-start',
    'dropdown-menu-sm-end',
    'dropdown-menu-md-start',
    'dropdown-menu-md-end',
    'dropdown-menu-lg-start',
    'dropdown-menu-lg-end',
    'dropdown-menu-xl-start',
    'dropdown-menu-xl-end',
    'dropdown-menu-xxl-start',
    'dropdown-menu-xxl-end'
];

public $primary_menu = '';
public $dropdown_menus = [];

/**
 * Start Level
 */
function start_lvl(&$output, $depth = 0, $args = null)
{
    $dropdown_menu_class = '';
    foreach ($this->current_item->classes as $class) {
        if (in_array($class, $this->dropdown_menu_alignment_values)) {
            $dropdown_menu_class .= ' ' . $class;
        }
    }
    $indent = str_repeat("\t", $depth);
    $submenu = ($depth > 0) ? ' dropdown-submenu' : '';
    $output .= "\n$indent<ul class=\"dropdown-menu$submenu$dropdown_menu_class position-relative w-100 border-0 p-0 depth_$depth\">\n";
}

/**
 * End Level
 */
function end_lvl(&$output, $depth = 0, $args = null)
{
    $output .= "</ul>\n";

    if ($depth === 0) {
        // Capture the top-level dropdown menus
        $this->dropdown_menus[] = $output;
        // Clear the output to prevent double rendering
        $output = '';
    }
}

/**
 * Start Element
 */
function start_el(&$output, $item, $depth = 0, $args = null, $id = 0)
{
    $this->current_item = $item;

    $indent = ($depth) ? str_repeat("\t", $depth) : '';

    $li_attributes = '';
    $class_names = $value = '';

    $classes = empty($item->classes) ? array() : (array) $item->classes;

    $classes[] = ($args->walker->has_children) ? 'dropdown' : '';
    $classes[] = 'nav-item';
    $classes[] = 'nav-item-' . $item->ID;
    if ($depth && $args->walker->has_children) {
        $classes[] = 'dropdown-menu-child-item dropdown-menu-end at_depth_' . $depth;
    }

    $class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
    $class_names = ' class="' . esc_attr($class_names) . '"';

    $id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
    $id = strlen($id) ? ' id="' . esc_attr($id) . '"' : '';

    $item_output = '';
    $item_output .= $indent . '<li ' . $id . $value . $class_names . $li_attributes . '>';

    $attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : '';
    $attributes .= !empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : '';
    $attributes .= !empty($item->xfn) ? ' rel="' . esc_attr($item->xfn) . '"' : '';
    $attributes .= !empty($item->url) ? ' href="' . esc_attr($item->url) . '"' : '';

    $active_class = ($item->current || $item->current_item_ancestor || in_array("current_page_parent", $item->classes, true) || in_array("current-post-ancestor", $item->classes, true)) ? 'active' : '';
    $nav_link_class = ($depth > 0) ? 'dropdown-item ' : 'nav-link ';

    if ($args->walker->has_children) {
        $attributes .= ' class="' . $nav_link_class . $active_class . ' d-flex dropdown-arrow" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false"';
    } else {
        $attributes .= ' class="' . $nav_link_class . $active_class . '"';
    }

    $item_output .= $args->before;
    $item_output .= '<a' . $attributes . '>';
    $item_output .= $args->link_before . apply_filters('the_title', $item->title, $item->ID) . $args->link_after;
    $item_output .= '</a>';
    $item_output .= $args->after;

    $output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);

    if ($depth === 0) {
        // Capture the primary menu items
        $this->primary_menu .= $output;
        // Clear the output to prevent double rendering
        $output = '';
    }
}

/**
 * End Element
 */
function end_el(&$output, $item, $depth = 0, $args = null)
{
    $output .= "</li>\n";
}}

The script:

document.addEventListener('DOMContentLoaded', function () { const navLinks = document.querySelectorAll('.navbar-nav > .nav-item > .nav-link.dropdown-arrow');  // Select first-level nav links with dropdown-toggle class

const dropdownMenus = document.querySelectorAll('.col-lg-3 > .card-menu > .card-body > .dropdown-menu');  // Select dropdown menus in the second column
navLinks.forEach((navLink, navIndex) => {
    navLink.addEventListener('click', function (event) {
      event.preventDefault();  // Prevent the default link behavior

      // Hide all dropdown menus
      dropdownMenus.forEach((menu, menuIndex) => {
        if (menuIndex === navIndex) {
          menu.classList.toggle('show');  // Toggle the show class only for the corresponding menu
        } else {
          menu.classList.remove('show');  // Ensure other menus are hidden
        }
      });
    });
  });
});

The HTML code:

<div class="offcanvas offcanvas-start" tabindex="-1" id="offCanvasMenu" aria-labelledby="offCanvasMenuLabel">
            <div class="offcanvas-body px-5">
                <div class="row h-100">
                    <div class="col-lg-3">
                        <div class="card card-menu border-0 h-100">
                            <div class="card-body p-0">
                                <ul class="navbar-nav">
                                    <?php
                                    $walker = new bootstrap_5_wp_nav_menu_walker();
                                    wp_nav_menu(
                                        array(
                                            'theme_location' => 'main-menu',
                                            'container' => false,
                                            'menu_class' => '',
                                            'fallback_cb' => '__return_false',
                                            'items_wrap' => '%3$s',  // Keep only the menu items
                                            'depth' => 4,
                                            'walker' => $walker
                                        )
                                    );
                                    // Output the primary menu items
                                    echo $walker->primary_menu;
                                    ?>
                                </ul>
                            </div>
                        </div>
                    </div>
                    <div class="col-lg-3">
                        <div class="card card-menu border-0 h-100">
                            <div class="card-body p-0">
                                <?php
                                // Output the captured dropdown menus
                                foreach ($walker->dropdown_menus as $dropdown_menu) {
                                    echo $dropdown_menu;
                                }
                                ?>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

Thank you

本文标签: navigationNav walker bootstrap Display 3rd level and 4th level in dropdown menu