0

I am having trouble trying to get a menu with dropdowns to work. This is the non-wordpress menu:

<ul class="nav navbar-nav" data-in="fadeInDown" data-out="fadeOutUp">
    <li class="dropdown">
        <a href="#" class="dropdown-toggle" data-toggle="dropdown" >Dropdowns</a>
        <ul class="dropdown-menu">
            <li><a href="#">Custom Menu</a></li>
            <li><a href="#">Custom Menu</a></li>
            <li class="dropdown">
                <a href="#" class="dropdown-toggle" data-toggle="dropdown" >Sub Menu</a>
                <ul class="dropdown-menu">
                    <li><a href="#">Custom Menu</a></li>
                    <li><a href="#">Custom Menu</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

I have tried to turn it into a wordpress menu like this:

<div class="collapse navbar-collapse" id="navbar-menu">
<?php 
    wp_nav_menu( array(

        'menu_class' => 'nav navbar-nav data-in="fadeInDown" data-out="fadeOutUp"',
        'container' => '',
        'depth' => 2,
        'theme_location' => 'main-menu',
        'walker' => new My_BS_Walker_Nav_Menu(),

    ));
?>
</div>

Here is the walker code but I am just confusing myself here:

<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly.
}

/**
 * Custom walker for WordPress custom menus.
 *
 * @link https://wordpress.stackexchange.com/q/298663/137402
 *
 * @see Walker_Nav_Menu
 */
class My_BS_Walker_Nav_Menu extends Walker_Nav_Menu {
    /**
     * Starts the list before the elements are added.
     *
     * @see Walker_Nav_Menu::start_lvl()
     */
    public function start_lvl( &$output, $depth = 0, $args = array() ) {
        // Default class.
        $classes = array( 'dropdown-menu' );

        /**
         * Filters the CSS class(es) applied to a menu list element.
         */
        $class_names = join( ' ', apply_filters( 'nav_menu_submenu_css_class', $classes, $args, $depth ) );
        $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

        $output .= '' .

                            "<ul{$class_names}>";
    }

    /**
     * Ends the list of after the elements are added.
     *
     * @see Walker_Nav_Menu::end_lvl()
     */
    public function end_lvl( &$output, $depth = 0, $args = array() ) {
        $output .= '' .
                            '</ul>'; // End .menu-vertical

    }

    /**
     * Starts the element output.
     *
     * @see Walker_Nav_Menu::start_el()
     */
    public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
        $item->item_spacing = 'discard';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        if ( in_array( 'menu-item-has-children', $classes ) ) {
            $depth2 = intval( $args->depth );
            // Displays a link to the page and not a "dropdown trigger" text.
            if ( $depth2 > 0 && (int) $depth + 1 === $depth2 ) {
                return parent::start_el( $output, $item, $depth, $args, $id );
            }
        } else {
            // Displays a link to the page and not a "dropdown trigger" text.
            return parent::start_el( $output, $item, $depth, $args, $id );
        }

        $classes[] = 'dropdown';
        $classes[] = 'menu-item-' . $item->ID;

        /**
         * Filters the CSS class(es) applied to a menu item's list item element.
         */
        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
        $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

        $output .= '<li' . $class_names .'>';

        /** This filter is documented in wp-includes/post-template.php */
        $title = apply_filters( 'the_title', $item->title, $item->ID );

        /**
         * Filters a menu item's title.
         */
        $title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );

        $item_output = '<a href="#" class="dropdown-toggle" data-toggle="dropdown" >';
        $item_output .= $title;
        $item_output .= '</a>';

        $output .= $item_output;
    }

    /**
     * Ends the element output, if needed.
     *
     * @see Walker_Nav_Menu::end_el()
     */
    public function end_el( &$output, $item, $depth = 0, $args = array() ) {
        $output .= '</li>';
    }

} // My_BS_Walker_Nav_Menu
2

The walker code is okay, but in order to have this markup:

<ul class="nav navbar-nav" data-in="fadeInDown" data-out="fadeOutUp">
    ...
</ul>

..in the array passed to the wp_nav_menu() function, set items_wrap to:

<ul id="%1$s" class="%2$s" data-in="fadeInDown" data-out="fadeOutUp">%3$s</ul>

So the full markup would be:

<div class="collapse navbar-collapse" id="navbar-menu">
<?php 
    wp_nav_menu( array(

        'menu_class' => 'nav navbar-nav',
        'container' => '',
        'depth' => 2,
        'theme_location' => 'main-menu',
        'walker' => new My_BS_Walker_Nav_Menu(),
        'items_wrap' => '<ul id="%1$s" class="%2$s" data-in="fadeInDown" data-out="fadeOutUp">%3$s</ul>',

    ));
?>
</div>

Or you can omit the menu_class parameter and simply add the classes via the items_wrap value:

<div class="collapse navbar-collapse" id="navbar-menu">
<?php 
    wp_nav_menu( array(

        'container' => '',
        'depth' => 2,
        'theme_location' => 'main-menu',
        'walker' => new My_BS_Walker_Nav_Menu(),
        'items_wrap' => '<ul id="%1$s" class="nav navbar-nav" data-in="fadeInDown" data-out="fadeOutUp">%3$s</ul>',

    ));
?>
</div>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.