Skip to content

Instantly share code, notes, and snippets.

@jakebellacera
Last active July 26, 2024 17:23
Show Gist options
  • Save jakebellacera/8c151a87975b4f0e369311be9d89d864 to your computer and use it in GitHub Desktop.
Save jakebellacera/8c151a87975b4f0e369311be9d89d864 to your computer and use it in GitHub Desktop.
Bootstrap 4 menus in WordPress via filters. No walker needed!

Bootstrap 4 menus in WordPress with filters

No walker needed!

This snippet allows you to create Bootstrap 4 menus without the use of a Walker. Instead, we're using filters to leverage WordPress core functionality as much as possible. Basically, all you need to do is this and you're done:

<nav class="navbar navbar-expand-lg fixed-top">
  <div class="container">
    <a class="navbar-brand" href="<?php echo home_url(); ?>">
      <?php echo bloginfo('name'); ?> 
    </a>

    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-expanded="false" aria-controls="navbarSupportedContent" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>

    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <?php
        wp_nav_menu(array(
          'menu'            => 'foo',
          'container'       => false,
          'menu_id'         => false,
          'menu_class'      => 'navbar-nav',
          'bootstrap'       => true
        ));
      ?>
    </div>
  </div>
</nav>

How to install

  1. Drop the PHP code below into your functions.php file of your theme.
  2. Add 'bootstrap' => true to your wp_nav_menu calls.
<?php
/**
* Bootstrap 4 menus in WordPress via filters. No walker needed!
*
* @author Jake Bellacera <https://github.com/jakebellacera>
*
* Instructions:
* 1. Drop this in your theme's functions.php.
* 2. Add 'bootstrap' => true to your wp_nav_menu args.
*
* Example:
* <?php wp_nav_menu(array('menu' => 'header', 'bootstrap' => true)); ?>
*/
/**
* Add bootstrap classes to individual menu list items
*/
function filter_bootstrap_nav_menu_css_class($classes, $item, $args) {
if (isset($args->bootstrap)) {
$classes[] = 'nav-item';
if (in_array('menu-item-has-children', $classes)) {
$classes[] = 'dropdown';
}
if (in_array('dropdown-header', $classes)) {
unset($classes[array_search('dropdown-header', $classes)]);
}
}
return $classes;
}
add_filter('nav_menu_css_class', 'filter_bootstrap_nav_menu_css_class', 10, 3);
/**
* Add bootstrap attributes to individual link elements.
*/
function filter_bootstrap_nav_menu_link_attributes($atts, $item, $args, $depth) {
if (isset($args->bootstrap)) {
if (!$atts['class']) {
$atts['class'] = '';
}
if ($depth > 0) {
if (in_array('dropdown-header', $item->classes)) {
$atts['class'] = 'dropdown-header';
} else {
$atts['class'] .= 'dropdown-item';
}
if ($item->description) {
$atts['class'] .= ' has-description';
}
} else {
$atts['class'] .= 'nav-link';
if (in_array('menu-item-has-children', $item->classes)) {
$atts['class'] .= ' dropdown-toggle';
$atts['role'] = 'button';
$atts['data-toggle'] = 'dropdown';
$atts['aria-haspopup'] = 'true';
$atts['aria-expanded'] = 'false';
}
}
}
return $atts;
}
add_filter('nav_menu_link_attributes', 'filter_bootstrap_nav_menu_link_attributes', 10, 4);
/**
* Add bootstrap classes to dropdown menus.
*/
function filter_bootstrap_nav_menu_submenu_css_class($classes, $args, $depth) {
if (isset($args->bootstrap)) {
$classes[] = 'dropdown-menu';
}
return $classes;
}
add_filter('nav_menu_submenu_css_class', 'filter_bootstrap_nav_menu_submenu_css_class', 10, 3);
@kannan-d-cbe
Copy link

u missed current-menu-item & current-{post_type}-ancestor to active

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment