The WordPress menu function wp_nav_menu() outputs a fixed HTML structure, and we usually write CSS against that structure. If your theme CSS is based on Bootstrap, reusing Bootstrap’s navigation styles is one of the easiest approaches. We only need to modify the HTML output of wp_nav_menu() so it matches the structure expected by Bootstrap.
Step 1: add a custom Walker_Nav_Menu class to the theme’s functions.php
class BS3_Walker_Nav_Menu extends Walker_Nav_Menu {
function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
$id_field = $this->db_fields['id'];
if ( isset( $args[0] ) && is_object( $args[0] ) )
{
$args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
}
return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
if ( is_object($args) && !empty($args->has_children) )
{
$link_after = $args->link_after;
$args->link_after = ' <b class="caret"></b>';
}
parent::start_el($output, $item, $depth, $args, $id);
if ( is_object($args) && !empty($args->has_children) )
$args->link_after = $link_after;
}
function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = '';
$output .= "$indent<ul class="dropdown-menu list-unstyled">";
}
}
Step 2: add a filter to change the remaining HTML
add_filter('nav_menu_link_attributes', 'nav_link_att', 10, 3);
function nav_link_att($atts, $item, $args) {
if ( $args->has_children )
{
$atts['data-toggle'] = 'dropdown';
$atts['class'] = 'dropdown-toggle';
}
return $atts;
}
Step 3: add the HTML to header.php
<nav id="nav" class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="row">
<div class="col-md-12">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header visible-xs">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#"></a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse navbar-ex1-collapse">
<?php wp_nav_menu(array(
'container_class' => 'menu-header',
'theme_location' => 'primary',
'items_wrap' => '<ul id="%1$s" class="%2$s nav navbar-nav">%3$s</ul>',
'walker' => new BS3_Walker_Nav_Menu,
'menu' => 'Your Menu'
)); ?>
</div><!-- /.navbar-collapse -->
</div>
</div>
</div>
</nav>
After those three steps, WordPress navigation menus can work with Bootstrap 3. By the same logic, if you use another CSS framework, you can adapt the menu output in a similar way to support that framework as well.
