How to integrate wp_nav_menu() WordPress with Bootstrap dropdown menu layout

14,404

Solution 1

Try using this navwalker you can put into your theme.

https://github.com/twittem/wp-bootstrap-navwalker

Solution 2

Here an alternate solution for https://github.com/twittem/wp-bootstrap-navwalker

namespace theme;

/**
 * Is Nav
 *
 * Check if nav menu has a `nav` or `navbar-nav` CSS class.
 *
 * @param stdClass $nav_menu An object of wp_nav_menu() arguments.
 *
 * @return bool
 */
function is_nav_menu_nav( $nav_menu )
{
    return preg_match( '/(^| )(nav|navbar-nav)( |$)/', $nav_menu->menu_class ); 
}

/**
 * CSS Class
 *
 * Add custom CSS classes to the nav menu item.
 *
 * @param array    $classes   Array of the CSS classes.
 * @param WP_Post  $item      The current menu item.
 * @param stdClass $nav_menu  An object of wp_nav_menu() arguments.
 * @param int      $depth     Depth of menu item.
 *
 * @return array
 */
function nav_menu_css_class( $classes, $item, $nav_menu, $depth )
{
    if ( ! is_nav_menu_nav( $nav_menu ) ) 
    {
        return $classes;
    }

    if ( $depth == 0 ) 
    {
        if ( in_array( 'menu-item-has-children', $item->classes ) ) 
        {
            $classes[] = 'dropdown';
        }

        else
        {
            $classes[] = 'nav-item';
        }
    }

    return $classes;
}

add_filter( 'nav_menu_css_class', 'theme\nav_menu_css_class', 5, 4 );

/**
 * Link Attributes
 *
 * Alter nav menu item link attributes.
 *
 * @param array    $atts      The HTML attributes applied to the menu item's <a> element.
 * @param WP_Post  $item      The current menu item.
 * @param stdClass $nav_menu  An object of wp_nav_menu() arguments.
 * @param int      $depth     Depth of menu item.
 *
 * @return array
 */
function nav_menu_link_attributes( $atts, $item, $nav_menu, $depth )
{
    if ( ! is_nav_menu_nav( $nav_menu ) ) 
    {
        return $atts;
    }

    // Make sure 'class' attribute is set.
    if ( ! isset( $atts['class'] ) ) $atts['class'] = '';

    // Nav link
    if ( $depth == 0 ) 
    {
        $atts['class'] .= ' nav-link';

        // Dropdown
        if ( in_array( 'menu-item-has-children', $item->classes ) ) 
        {
            $atts['href'] = '#';
            $atts['class'] .= ' dropdown-toggle';
            $atts['data-toggle']   = 'dropdown';
            $atts['aria-haspopup'] = 'true';
            $atts['aria-expanded'] = 'false';
        }
    }

    // Dropdown item
    else if ( $depth == 1 )
    {
        $atts['class'] .= ' dropdown-item';
    }

    // Active
    if ( $item->current || $item->current_item_ancestor || $item->current_item_parent ) 
    {
        $atts['class'] .= ' active';
    }

    // Sanitize 'class' attribute.
    $atts['class'] = trim( $atts['class'] );

    return $atts;
}

add_filter( 'nav_menu_link_attributes', 'theme\nav_menu_link_attributes', 5, 4 );

/**
 * Submenu CSS Class
 *
 * Add custom CSS classes to the nav menu submenu.
 *
 * @param array    $classes   Array of the CSS classes that are applied to the menu <ul> element.
 * @param stdClass $nav_menu  An object of wp_nav_menu() arguments.
 * @param int      $depth     Depth of menu item.
 *
 * @return array
 */
function nav_menu_submenu_css_class( $classes, $nav_menu, $depth )
{
    if ( is_nav_menu_nav( $nav_menu ) ) 
    {
        $classes[] = 'dropdown-menu';
    }

    return $classes;
}

add_filter( 'nav_menu_submenu_css_class', 'theme\nav_menu_submenu_css_class', 5, 3 );

Usage:

Add menu_class nav or navbar-nav

wp_nav_menu( array
(
    'theme_location' => 'my-location-1', 
    'menu_class'     => 'nav',
));

wp_nav_menu( array
(
    'theme_location' => 'my-location-2', 
    'menu_class'     => 'navbar-nav',
));

Solution 3

This can be done more simply with some jquery, but it's not too elegant and i bet is not recommended either. You could check to see what class wp adds to your ul element and based on that do some logic, something like:

jQuery(document).ready(function($)
{
    if( $('ul').hasClass('sub-menu') )
    {
        var parent = $('ul .sub-menu').parent();
        $('ul .sub-menu').addClass('dropdown-menu');
        parent.addClass('dropdown');
        parent.children(':first-child').attr({'href': '#', 'class': 'dropdown-toggle', 'data-toggle': 'dropdown'});

        }
});
Share:
14,404
Rodrigo Schneider
Author by

Rodrigo Schneider

Fintech with focus on cryptomarket for B2C and B2B clients. I’m the Front-end Head and Engineer of the Front-end Web Team. I’m currently leading a team of another 2 developers and we are responsible for all the web projects of the company, being them: the web app, the websites and internal systems.

Updated on June 26, 2022

Comments

  • Rodrigo Schneider
    Rodrigo Schneider almost 2 years

    I'm trying to integrate the bootstrap navbar dropdown with Wordpress. I already have the navbar working perfectly. But when I try to add a new category/page as a submenu, the layout break, with an "ul" element with decoration (dot) and has no dropdown hover effect. I tried the code from nav walker but didn't work. If have some way to make it without nav walker too, it'd be good.

  • Rodrigo Schneider
    Rodrigo Schneider over 8 years
    Hey man! Thank you so much! Have tried it before but had problem with the PHP. Now without require once, I just copy and paste the code in my function.php and it's working!!!
  • Cedon
    Cedon over 8 years
    You're welcome. I had a similar problem a while back when I was playing with WordPress and Bootstrap and had to use this.