I want to use Bootstrap Navbar menu in Wordpress. What menu class will be used When it will be dynamic through Wordpress. What Menu class have to have in question mark for bellow markup?
<?Php
wp_nav_menu(array(
'theme_location' =>'main-menu',
'menu_class' =>'?????'
));
?>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
.....
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<div class="form-group">
</div>
<ul class="nav navbar-nav navbar-right">
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
You can use wp_bootstrap_navwalker.php for any classes
<?php
wp_nav_menu(array(
'menu' => 'main-menu',
'menu_class' => 'nav navbar-nav',
'walker' => new wp_bootstrap_navwalker())
);
?>
You can configure like this
create wp_bootstrap_navwalker.php coppy this code in wp_bootstrap_navwalker.php in your theam
<?php
/**
* Class Name: wp_bootstrap_navwalker
* GitHub URI: https://github.com/twittem/wp-bootstrap-navwalker
* Description: A custom WordPress nav walker class to implement the Bootstrap 3 navigation style in a custom theme using the WordPress built in menu manager.
* Version: 2.0.4
* Author: Edward McIntyre - #twittem
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/
class wp_bootstrap_navwalker extends Walker_Nav_Menu {
/**
* #see Walker::start_lvl()
* #since 3.0.0
*
* #param string $output Passed by reference. Used to append additional content.
* #param int $depth Depth of page. Used for padding.
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat( "\t", $depth );
$output .= "\n$indent<ul role=\"menu\" class=\" dropdown-menu\">\n";
}
/**
* #see Walker::start_el()
* #since 3.0.0
*
* #param string $output Passed by reference. Used to append additional content.
* #param object $item Menu item data object.
* #param int $depth Depth of menu item. Used for padding.
* #param int $current_page Menu item ID.
* #param object $args
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
/**
* Dividers, Headers or Disabled
* =============================
* Determine whether the item is a Divider, Header, Disabled or regular
* menu item. To prevent errors we use the strcasecmp() function to so a
* comparison that is not case sensitive. The strcasecmp() function returns
* a 0 if the strings are equal.
*/
if ( strcasecmp( $item->attr_title, 'divider' ) == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="divider">';
} else if ( strcasecmp( $item->title, 'divider') == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="divider">';
} else if ( strcasecmp( $item->attr_title, 'dropdown-header') == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="dropdown-header">' . esc_attr( $item->title );
} else if ( strcasecmp($item->attr_title, 'disabled' ) == 0 ) {
$output .= $indent . '<li role="presentation" class="disabled">' . esc_attr( $item->title ) . '';
} else {
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
if ( $args->has_children )
$class_names .= ' dropdown';
if ( in_array( 'current-menu-item', $classes ) )
$class_names .= ' active';
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li' . $id . $value . $class_names .'>';
$atts = array();
$atts['title'] = ! empty( $item->title ) ? $item->title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
// If item has_children add atts to a.
if ( $args->has_children && $depth === 0 ) {
$atts['href'] = '#';
$atts['data-toggle'] = 'dropdown';
$atts['class'] = 'dropdown-toggle';
$atts['aria-haspopup'] = 'true';
} else {
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
}
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
$item_output = $args->before;
/*
* Glyphicons
* ===========
* Since the the menu item is NOT a Divider or Header we check the see
* if there is a value in the attr_title property. If the attr_title
* property is NOT null we apply it as the class name for the glyphicon.
*/
if ( ! empty( $item->attr_title ) )
$item_output .= '<a'. $attributes .'><span class="glyphicon ' . esc_attr( $item->attr_title ) . '"></span> ';
else
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= ( $args->has_children && 0 === $depth ) ? ' <span class="caret"></span></a>' : '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
/**
* Traverse elements to create list from elements.
*
* Display one element if the element doesn't have any children otherwise,
* display the element and its children. Will only traverse up to the max
* depth and no ignore elements under that depth.
*
* This method shouldn't be called directly, use the walk() method instead.
*
* #see Walker::start_el()
* #since 2.5.0
*
* #param object $element Data object
* #param array $children_elements List of elements to continue traversing.
* #param int $max_depth Max depth to traverse.
* #param int $depth Depth of current element.
* #param array $args
* #param string $output Passed by reference. Used to append additional content.
* #return null Null on failure with no changes to parameters.
*/
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
if ( ! $element )
return;
$id_field = $this->db_fields['id'];
// Display this element.
if ( is_object( $args[0] ) )
$args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
/**
* Menu Fallback
* =============
* If this function is assigned to the wp_nav_menu's fallback_cb variable
* and a manu has not been assigned to the theme location in the WordPress
* menu manager the function with display nothing to a non-logged in user,
* and will add a link to the WordPress menu manager if logged in as an admin.
*
* #param array $args passed from the wp_nav_menu function.
*
*/
public static function fallback( $args ) {
if ( current_user_can( 'manage_options' ) ) {
extract( $args );
$fb_output = null;
if ( $container ) {
$fb_output = '<' . $container;
if ( $container_id )
$fb_output .= ' id="' . $container_id . '"';
if ( $container_class )
$fb_output .= ' class="' . $container_class . '"';
$fb_output .= '>';
}
$fb_output .= '<ul';
if ( $menu_id )
$fb_output .= ' id="' . $menu_id . '"';
if ( $menu_class )
$fb_output .= ' class="' . $menu_class . '"';
$fb_output .= '>';
$fb_output .= '<li>Add a menu</li>';
$fb_output .= '</ul>';
if ( $container )
$fb_output .= '</' . $container . '>';
echo $fb_output;
}
}
}
?>
All dynamic handling in bootstrap using the supplied style sheets is controlled through classes like col-xs-2 or col-sm-1. The xs or sm defines the minimum resolution where the effect takes place and the number describes sensitivity of the effect.
Related
I'm converting the static HTML/CSS menu into the WordPress menu, it works fine for me in case there's no dropdown, no child menu but I want to make changes in code so I could work fine even for the dropdown menu, now in my case, if I put dropdown menu using WordPress menu, it breaks website header design.
Into Header.php
<?php wp_nav_menu(array(
'menu' => 'HeaderMenu',
'menu_class' => 'navbar-nav mr-auto',
'container' => '',
'li_class' => 'nav-item',
'a_class' => 'nav-link',
'active_class' =>'active' ,
)); ?>
Into Functions.php
register_nav_menus(array(
'HeaderMenu' => __( 'Header Menu', 'theme')
));
function add_class_li($classes, $item, $args){
if(isset($args-> li_class)){
$classes[] = $args->li_class;
}
if(isset($args-> active_class) && in_array('current-menu-item', $classes)){
$classes[] = $args->active_class;
}
return $classes;
}
add_filter('nav_menu_css_class', 'add_class_li',10,3);
function add_anchor_class($attr, $item, $args){
if(isset($args-> a_class)){
$attr['class'] = $args->a_class;
}return $attr;
}
add_filter('nav_menu_link_attributes', 'add_anchor_class',10,3);
HTML/CSS CODE
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="index.html">HOME<span class="sr-only">(current)</span></a> </li>
<li class="nav-item">
<a class="nav-link" href="about.html">ABOUT</a></li>
<li class="nav-item">
<a class="nav-link" href="service.html">SERVICES</a></li>
<li class="#" href="#">
<a class="nav-link" href="blog.html">BLOG</a></li>
<li class="nav-item" href="#">
<a class="nav-link" href="contact.html">CONTACT</a></li>
<li class="last"><img src="images/search-icon.png" alt="icon"></li>
</ul>
Add this custom nav Walker class in you theme's functions.php
class Custom_Nav_Walker extends Walker_Nav_Menu
{
/**
* #var array $menu_items
*/
private $menu_items;
/**
* #var int $last_menu_id
*/
private $last_menu_id;
/**
* #var int $first_menu_id
*/
private $first_menu_id;
/**
* #inheritdoc
*/
public function start_el( &$output, $item, $depth = 0, $args = null, $id = 0 ) {
if( is_null( $this->menu_items ) ) {
$this->menu_items = wp_get_nav_menu_items( $args->theme_location );
if( $this->menu_items != false ) {
$first_menu_index = array_key_first( $this->menu_items );
$last_menu_index = array_key_last( $this->menu_items );
$this->first_menu_id = $this->menu_items[ $first_menu_index ]->ID;
$this->last_menu_id = $this->menu_items[ $last_menu_index ]->ID;
}
}
if ( isset( $args->item_spacing ) && 'discard' === $args->item_spacing ) {
$t = '';
$n = '';
} else {
$t = "\t";
$n = "\n";
}
$indent = ( $depth ) ? str_repeat( $t, $depth ) : '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
/**
* Filters the arguments for a single nav menu item.
*
* #since 4.4.0
*
* #param stdClass $args An object of wp_nav_menu() arguments.
* #param WP_Post $item Menu item data object.
* #param int $depth Depth of menu item. Used for padding.
*/
$args = apply_filters( 'nav_menu_item_args', $args, $item, $depth );
/**
* Filters the CSS classes applied to a menu item's list item element.
*
* #since 3.0.0
* #since 4.1.0 The `$depth` parameter was added.
*
* #param string[] $classes Array of the CSS classes that are applied to the menu item's `<li>` element.
* #param WP_Post $item The current menu item.
* #param stdClass $args An object of wp_nav_menu() arguments.
* #param int $depth Depth of menu item. Used for padding.
*/
$class_names = apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth );
$custom_menu_class = [ 'nav-item' ];
if( in_array( 'current-menu-item', $class_names ) ) {
$custom_menu_class[] = 'active';
}
$class_names = implode( ' ', $custom_menu_class);
if( $item->ID == $this->last_menu_id ) {
$class_names = ' class="last"';
} else {
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
}
$output .= $indent . '<li' . $class_names . '>';
$atts = array();
$atts['title'] = ! empty( $item->attr_title ) ? $item->attr_title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
if ( '_blank' === $item->target && empty( $item->xfn ) ) {
$atts['rel'] = 'noopener';
} else {
$atts['rel'] = $item->xfn;
}
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
$atts['aria-current'] = $item->current ? 'page' : '';
/**
* Filters the HTML attributes applied to a menu item's anchor element.
*
* #since 3.6.0
* #since 4.1.0 The `$depth` parameter was added.
*
* #param array $atts {
* The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored.
*
* #type string $title Title attribute.
* #type string $target Target attribute.
* #type string $rel The rel attribute.
* #type string $href The href attribute.
* #type string $aria_current The aria-current attribute.
* }
* #param WP_Post $item The current menu item.
* #param stdClass $args An object of wp_nav_menu() arguments.
* #param int $depth Depth of menu item. Used for padding.
*/
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( is_scalar( $value ) && '' !== $value && false !== $value ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
/** 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.
*
* #since 4.4.0
*
* #param string $title The menu item's title.
* #param WP_Post $item The current menu item.
* #param stdClass $args An object of wp_nav_menu() arguments.
* #param int $depth Depth of menu item. Used for padding.
*/
$title = apply_filters( 'nav_menu_item_title', $title, $item, $args, $depth );
if( $item->ID == $this->last_menu_id ) {
$item_output = '<img src="images/search-icon.png" alt="icon">';
} else if ( $item->ID == $this->first_menu_id ) {
$item_output = $args->before;
$item_output .= '<a' . $attributes . '>';
$item_output .= $args->link_before . $title . '<span class="sr-only">(current)</span>';
$item_output .= '</a>';
$item_output .= $args->after;
} else {
$item_output = $args->before;
$item_output .= '<a' . $attributes . '>';
$item_output .= $args->link_before . $title . $args->link_after;
$item_output .= '</a>';
$item_output .= $args->after;
}
/**
* Filters a menu item's starting output.
*
* The menu item's starting output only includes `$args->before`, the opening `<a>`,
* the menu item's title, the closing `</a>`, and `$args->after`. Currently, there is
* no filter for modifying the opening and closing `<li>` for a menu item.
*
* #since 3.0.0
*
* #param string $item_output The menu item's starting HTML output.
* #param WP_Post $item Menu item data object.
* #param int $depth Depth of menu item. Used for padding.
* #param stdClass $args An object of wp_nav_menu() arguments.
*/
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
and then add this class into wp_nav_menu via walker argument.
wp_nav_menu(
array(
'theme_location' => 'your theme location',
'echo' => true,
'walker' => new Custom_Nav_Walker(),
'menu_class' => 'navbar-nav mr-auto'
)
);
also no need to add any extra filter for menu classes.
Hello I am working on a Wordpress theme and I continue to get a fatal error message:
Fatal error: Class 'wp_bootstrap_navwalker' not found in /Applications/XAMPP/xamppfiles/apps/wordpress/htdocs/wp-content/themes/wpbootstrap/header.php on line 35
Can someone please help me identify what changes I need to make in which file? I have been following a youtube video step by step: https://www.youtube.com/watch?v=t-AGjdMrtdA
Function.php
<?php
// Register Nav Walker class_alias
require_once('wp_bootstrap_navwalker.php');
// Theme Support
function wpb_theme_setup(){
// Nav Menus
register_nav_menus(array(
'primary' => __('Primary Menu', 'wpbootstrap')
));
}
add_action('after_setup_theme','wpb_theme_setup');
header.php
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo("charset"); ?>">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="<?php bloginfo('description') ?>">
<title>
<?php bloginfo('name'); ?> |
<?php is_front_page() ? bloginfo('description') : wp_title(); ?>
</title>
<!-- Bootstrap core CSS -->
<link href="<?php bloginfo('template_url');?>/css/bootstrap.css" rel="stylesheet">
<!-- Custom styles for this template -->
<link href="<?php bloginfo('stylesheet_url');?>" rel="stylesheet">
<?php wp_head (); ?>
</head>
<body>
<div class="blog-masthead">
<div class="container">
<nav class="blog-nav">
<?php
wp_nav_menu( array(
'menu' => 'primary',
'theme_location' => 'primary',
'depth' => 2,
'container' => 'div',
'container_class' => 'collapse navbar-collapse',
'container_id' => 'bs-example-navbar-collapse-1',
'menu_class' => 'nav navbar-nav',
'fallback_cb' => 'WP_Bootstrap_Navwalker::fallback',
'walker' => new wp_bootstrap_navwalker())
);
?>
</nav>
</div>
</div>
<div class="container">
<div class="blog-header">
<h1 class="blog-title"><?php bloginfo('name'); ?></h1>
<p class="lead blog-description"><?php bloginfo('description'); ?></p>
</div>
wp-bootstrap-navwalker.php
<?php
/**
* WP Bootstrap Navwalker
*
* #package WP-Bootstrap-Navwalker
*/
/**
* Class Name: WP_Bootstrap_Navwalker
* Plugin Name: WP Bootstrap Navwalker
* Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker
* Description: A custom WordPress nav walker class to implement the Bootstrap 3 navigation style in a custom theme using the WordPress built in menu manager.
* Author: Edward McIntyre - #twittem, WP Bootstrap
* Version: 2.0.5
* Author URI: https://github.com/wp-bootstrap
* GitHub Plugin URI: https://github.com/wp-bootstrap/wp-bootstrap-navwalker
* GitHub Branch: master
* License: GPL-3.0+
* License URI: http://www.gnu.org/licenses/gpl-3.0.txt
*/
/* Check if Class Exists. */
if ( ! class_exists( 'WP_Bootstrap_Navwalker' ) ) {
/**
* WP_Bootstrap_Navwalker class.
*
* #extends Walker_Nav_Menu
*/
class WP_Bootstrap_Navwalker extends Walker_Nav_Menu {
/**
* Start Level.
*
* #see Walker::start_lvl()
* #since 3.0.0
*
* #access public
* #param mixed $output Passed by reference. Used to append additional content.
* #param int $depth (default: 0) Depth of page. Used for padding.
* #param array $args (default: array()) Arguments.
* #return void
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat( "\t", $depth );
$output .= "\n$indent<ul role=\"menu\" class=\" dropdown-menu\" >\n";
}
/**
* Start El.
*
* #see Walker::start_el()
* #since 3.0.0
*
* #access public
* #param mixed $output Passed by reference. Used to append additional content.
* #param mixed $item Menu item data object.
* #param int $depth (default: 0) Depth of menu item. Used for padding.
* #param array $args (default: array()) Arguments.
* #param int $id (default: 0) Menu item ID.
* #return void
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
/**
* Dividers, Headers or Disabled
* =============================
* Determine whether the item is a Divider, Header, Disabled or regular
* menu item. To prevent errors we use the strcasecmp() function to so a
* comparison that is not case sensitive. The strcasecmp() function returns
* a 0 if the strings are equal.
*/
if ( 0 === strcasecmp( $item->attr_title, 'divider' ) && 1 === $depth ) {
$output .= $indent . '<li role="presentation" class="divider">';
} elseif ( 0 === strcasecmp( $item->title, 'divider' ) && 1 === $depth ) {
$output .= $indent . '<li role="presentation" class="divider">';
} elseif ( 0 === strcasecmp( $item->attr_title, 'dropdown-header' ) && 1 === $depth ) {
$output .= $indent . '<li role="presentation" class="dropdown-header">' . esc_attr( $item->title );
} elseif ( 0 === strcasecmp( $item->attr_title, 'disabled' ) ) {
$output .= $indent . '<li role="presentation" class="disabled">' . esc_attr( $item->title ) . '';
} else {
$value = '';
$class_names = $value;
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
if ( $args->has_children ) {
$class_names .= ' dropdown';
}
if ( in_array( 'current-menu-item', $classes, true ) ) {
$class_names .= ' active';
}
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li itemscope="itemscope" itemtype="https://www.schema.org/SiteNavigationElement"' . $id . $value . $class_names . '>';
$atts = array();
if ( empty( $item->attr_title ) ) {
$atts['title'] = ! empty( $item->title ) ? strip_tags( $item->title ) : '';
} else {
$atts['title'] = $item->attr_title;
}
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
// If item has_children add atts to a.
if ( $args->has_children && 0 === $depth ) {
$atts['href'] = '#';
$atts['data-toggle'] = 'dropdown';
$atts['class'] = 'dropdown-toggle';
$atts['aria-haspopup'] = 'true';
} else {
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
}
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
$item_output = $args->before;
/*
* Glyphicons/Font-Awesome
* ===========
* Since the the menu item is NOT a Divider or Header we check the see
* if there is a value in the attr_title property. If the attr_title
* property is NOT null we apply it as the class name for the glyphicon.
*/
if ( ! empty( $item->attr_title ) ) {
$pos = strpos( esc_attr( $item->attr_title ), 'glyphicon' );
if ( false !== $pos ) {
$item_output .= '<a' . $attributes . '><span class="glyphicon ' . esc_attr( $item->attr_title ) . '" aria-hidden="true"></span> ';
} else {
$item_output .= '<a' . $attributes . '><i class="fa ' . esc_attr( $item->attr_title ) . '" aria-hidden="true"></i> ';
}
} else {
$item_output .= '<a' . $attributes . '>';
}
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= ( $args->has_children && 0 === $depth ) ? ' <span class="caret"></span></a>' : '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
} // End if().
}
/**
* Traverse elements to create list from elements.
*
* Display one element if the element doesn't have any children otherwise,
* display the element and its children. Will only traverse up to the max
* depth and no ignore elements under that depth.
*
* This method shouldn't be called directly, use the walk() method instead.
*
* #see Walker::start_el()
* #since 2.5.0
*
* #access public
* #param mixed $element Data object.
* #param mixed $children_elements List of elements to continue traversing.
* #param mixed $max_depth Max depth to traverse.
* #param mixed $depth Depth of current element.
* #param mixed $args Arguments.
* #param mixed $output Passed by reference. Used to append additional content.
* #return null Null on failure with no changes to parameters.
*/
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
if ( ! $element ) {
return; }
$id_field = $this->db_fields['id'];
// Display this element.
if ( is_object( $args[0] ) ) {
$args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] ); }
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
/**
* Menu Fallback
* =============
* If this function is assigned to the wp_nav_menu's fallback_cb variable
* and a menu has not been assigned to the theme location in the WordPress
* menu manager the function with display nothing to a non-logged in user,
* and will add a link to the WordPress menu manager if logged in as an admin.
*
* #param array $args passed from the wp_nav_menu function.
*/
public static function fallback( $args ) {
if ( current_user_can( 'edit_theme_options' ) ) {
/* Get Arguments. */
$container = $args['container'];
$container_id = $args['container_id'];
$container_class = $args['container_class'];
$menu_class = $args['menu_class'];
$menu_id = $args['menu_id'];
if ( $container ) {
echo '<' . esc_attr( $container );
if ( $container_id ) {
echo ' id="' . esc_attr( $container_id ) . '"';
}
if ( $container_class ) {
echo ' class="' . sanitize_html_class( $container_class ) . '"'; }
echo '>';
}
echo '<ul';
if ( $menu_id ) {
echo ' id="' . esc_attr( $menu_id ) . '"'; }
if ( $menu_class ) {
echo ' class="' . esc_attr( $menu_class ) . '"'; }
echo '>';
echo '<li>' . esc_attr( 'Add a menu', '' ) . '</li>';
echo '</ul>';
if ( $container ) {
echo '</' . esc_attr( $container ) . '>'; }
}
}
}
} // End if().
The next step is to create the WP_Bootstrap_Navwalker.php and include it. Put the following line into functions.php: file require_once(get_template_directory() . "/inc/wp-bootstrap-navwalker.php");
This assumes that the file is in an /inc folder. If the site now runs without error, the final step is to add the 'walker' => new WP_Bootstrap_Navwalker() line to the wp_nav_menu call.
More info: https://github.com/wp-bootstrap/wp-bootstrap-navwalker
Try to update your code here:
<?php
wp_nav_menu( array(
'menu' => 'primary',
'theme_location' => 'primary',
'depth' => 2,
'container' => 'div',
'container_class' => 'collapse navbar-collapse',
'container_id' => 'bs-example-navbar-collapse-1',
'menu_class' => 'nav navbar-nav',
'fallback_cb' => 'WP_Bootstrap_Navwalker::fallback',
'walker' => new WP_Bootstrap_Navwalker()
));
?>
I hope it will be helpful for you
There is no problem in the code.
Actually, you have done the mistake while saving the functions.php. The mistake is instead of "functions.php" you have saved it as "function.php". This is why the fatal error is appearing.
I did go through this: https://www.elegantthemes.com/blog/tips-tricks/how-to-create-custom-menu-structures-in-wordpress
I did as per the article above to create sub menu of 3rd level. However, In front end the third level of product category for Woocommerce (green apple) not showing up in the dropdown list.
I also read one of stackoverflow answer which says its not possible to create third-level sub menu. I do believe there's a workaround for this. Please advise me.
Thank you.
Tried as per #Rafin's answer,
If third level placed after all second level, then it shows up but this is not where the sub menus for second level menu (apple) supposed to be.
in the backend, placed after all second level menus
Shows up this way in front end,
But I need it to be arranged this way:
You can use following Walker Class that extends Wordpress Nav Menu
<?php
class ods_bootstrap_navwalker extends Walker_Nav_Menu {
/**
* #see Walker::start_lvl()
* #since 3.0.0
*
* #param string $output Passed by reference. Used to append additional content.
* #param int $depth Depth of page. Used for padding.
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat( "\t", $depth );
$output .= "\n$indent<div class=\"drop\"><ul role=\"menu\" class=\" dropdown-menu\">\n";
}
/**
* #see Walker::start_el()
* #since 3.0.0
*
* #param string $output Passed by reference. Used to append additional content.
* #param object $item Menu item data object.
* #param int $depth Depth of menu item. Used for padding.
* #param int $current_page Menu item ID.
* #param object $args
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
/**
* Dividers, Headers or Disabled
* =============================
* Determine whether the item is a Divider, Header, Disabled or regular
* menu item. To prevent errors we use the strcasecmp() function to so a
* comparison that is not case sensitive. The strcasecmp() function returns
* a 0 if the strings are equal.
*/
if ( strcasecmp( $item->attr_title, 'divider' ) == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="divider">';
} else if ( strcasecmp( $item->title, 'divider') == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="divider">';
} else if ( strcasecmp( $item->attr_title, 'dropdown-header') == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="dropdown-header">' . esc_attr( $item->title );
} else if ( strcasecmp($item->attr_title, 'disabled' ) == 0 ) {
$output .= $indent . '<li role="presentation" class="disabled">' . esc_attr( $item->title ) . '';
} else {
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'scroll menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
if ( $args->has_children )
$class_names .= ' dropdown';
if ( in_array( 'current-menu-item', $classes ) )
$class_names .= ' active';
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li' . $id . $value . $class_names .'>';
$atts = array();
$atts['title'] = ! empty( $item->title ) ? $item->title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
$atts['class'] = "back-top";
// If item has_children add atts to a.
if ( $args->has_children && $depth === 0 ) {
$atts['href'] = '#';
$atts['data-toggle'] = 'dropdown';
$atts['class'] = 'dropdown-toggle';
$atts['aria-haspopup'] = 'true';
} else {
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
}
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
$item_output = $args->before;
/*
* Glyphicons
* ===========
* Since the the menu item is NOT a Divider or Header we check the see
* if there is a value in the attr_title property. If the attr_title
* property is NOT null we apply it as the class name for the glyphicon.
*/
if ( ! empty( $item->attr_title ) )
$item_output .= '<a'. $attributes .'><span class="glyphicon ' . esc_attr( $item->attr_title ) . '"></span> ';
else
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= ( $args->has_children && 0 === $depth ) ? ' <span class="icon-play"></span></a>' : '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
/**
* Traverse elements to create list from elements.
*
* Display one element if the element doesn't have any children otherwise,
* display the element and its children. Will only traverse up to the max
* depth and no ignore elements under that depth.
*
* This method shouldn't be called directly, use the walk() method instead.
*
* #see Walker::start_el()
* #since 2.5.0
*
* #param object $element Data object
* #param array $children_elements List of elements to continue traversing.
* #param int $max_depth Max depth to traverse.
* #param int $depth Depth of current element.
* #param array $args
* #param string $output Passed by reference. Used to append additional content.
* #return null Null on failure with no changes to parameters.
*/
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
if ( ! $element )
return;
$id_field = $this->db_fields['id'];
// Display this element.
if ( is_object( $args[0] ) )
$args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
/**
* Menu Fallback
* =============
* If this function is assigned to the ods_nav_menu's fallback_cb variable
* and a manu has not been assigned to the theme location in the WordPress
* menu manager the function with display nothing to a non-logged in user,
* and will add a link to the WordPress menu manager if logged in as an admin.
*
* #param array $args passed from the ods_nav_menu function.
*
*/
public static function fallback( $args ) {
if ( current_user_can( 'manage_options' ) ) {
extract( $args );
$fb_output = null;
if ( $container ) {
$fb_output = '<' . $container;
if ( $container_id )
$fb_output .= ' id="' . $container_id . '"';
if ( $container_class )
$fb_output .= ' class="' . $container_class . '"';
$fb_output .= '>';
}
$fb_output .= '<ul';
if ( $menu_id )
$fb_output .= ' id="' . $menu_id . '"';
if ( $menu_class )
$fb_output .= ' class="' . $menu_class . '"';
$fb_output .= '>';
$fb_output .= '<li>Add a menu</li>';
$fb_output .= '</ul>';
if ( $container )
$fb_output .= '</' . $container . '>';
echo $fb_output;
}
}
}
And you can display menu with
<?php
wp_nav_menu( array(
'menu' => your_menu_name,
'theme_location' => your_menu_location,
'depth' => 3,
'container' => '',
'container_class' => '',
'container_id' => 'bs-example-navbar-collapse-1',
'menu_class' => 'navigation',
'fallback_cb' => 'ods_bootstrap_navwalker::fallback',
'walker' => new ods_bootstrap_navwalker())
);
?>
Take a reference to https://developer.wordpress.org/reference/classes/walker_nav_menu/
The easy code is here you can customize your HTML whatever you want
$parent = array();
$menu_name = 'menu-1'; //change menu name
if (($locations = get_nav_menu_locations()) && isset($locations[$menu_name]))
{
$menu = wp_get_nav_menu_object($locations[$menu_name]);
$menu_items = wp_get_nav_menu_items($menu->term_id);
$parent_id = 0;
foreach((array)$menu_items as $key => $menu_item)
{
if($menu_item->menu_item_parent == 0)
{
$parent_id = $menu_item->db_id;
$title = $menu_item->title;
$url = $menu_item->url;
array_push($parent, array("title" => $title, "url" => $url, "child" => array()));
}
else if($menu_item->menu_item_parent == $parent_id)
{
$childId = $menu_item->ID;
$title = $menu_item->title;
$url = $menu_item->url;
array_push($parent[count($parent) - 1]["child"], array("ID"=>$childId,"title" => $title, "url" => $url));
}
}
}
foreach($parent as $key=>$childval){
$parent[$key]['child']['subchild'];
if (!empty($childval['child'])) {
for($i=0;$i<count($childval['child']);$i++){
foreach($menu_items as $childitems){
if($childitems->menu_item_parent==$childval['child'][$i]['ID']){
$values = array("ID"=>$childitems->ID,"title" => $childitems->title, "url" => $childitems->url);
$parent[$key]['child'][$i]['childvalue'][] = $values;
}
}
}
}
}
echo "<pre>";
print_r($parent);
?
this will print your array then modify according to you.
thank me later..
the demo HTML is here
<ul class="nav navbar-nav">
<?php
foreach ($parent as $key => $value)
{
if(empty($value["child"]))
{
echo "<li><a href='" . $value["url"] . "'>" . $value["title"] . "</a></li>";
}
else
{
echo '<li class="dropdown">' . $value["title"] . ' <b class="caret"></b><ul class="dropdown-menu">';
foreach ($value["child"] as $key => $value)
{
echo '<li>' . $value["title"] . '</li>';
echo "<ul>";
foreach ($value['childvalue'] as $childval ){
echo '<li>' . $childval["title"] . '</li>';
}
echo "</ul>";
}
echo '</ul></li>';
}
}
?>
</ul>
You can use this code to display 3 levels hierarchical menu
Add this code in the function.php file.
function create_bootstrap_menu( $theme_location ) {
if ( ($theme_location) && ($locations = get_nav_menu_locations()) && isset($locations[$theme_location]) ) {
$menu = get_term( $locations[$theme_location], 'nav_menu' );
$menu_items = wp_get_nav_menu_items($menu->term_id);
//echo '<pre>'; print_r($menu_items); die;
$menu_list = '<ul>';
$menucount = 1;
$bool = true;
foreach( $menu_items as $menu_item ) {
if( $menu_item->menu_item_parent == 0 ) {
$parent = $menu_item->ID;
$menu_array = array();
foreach( $menu_items as $submenu ) {
if( $submenu->menu_item_parent == $parent ) {
$bool = true;
$menu_array[] = '<li class="dropdown"><a href="' . $submenu->url . '" >' . $submenu->title . '</a><ul>';
$parents = $submenu->ID;
foreach($menu_items as $submenus){
if( $submenus->menu_item_parent == $parents ) {
$menu_array[] .= '<li><a href="' . $submenus->url . '" >' . $submenus->title . '</a></li>';
}
}
$menu_array[] .= '</ul></li>';
}
}
if( $bool == true && count( $menu_array ) > 0 ) {
$menu_list .= '<li class="dropdown">';
$menu_list .= '<span>'.$menu_item->title.'</span> <i class="bi bi-chevron-down"></i>';
$menu_list .= '<ul>' ."\n";
$menu_list .= implode( $menu_array );
$menu_list .= '</ul>';
} else {
// echo "<pre>"; print_r($menu_item);
$menu_list .= '<li>';
$menu_list .= '<a class="nav-link scrollto active" href="'.$menu_item->url.'">' . $menu_item->title . '</a>';
}
}
// end <li>
$menu_list .= '</li>';
$menucount++;
}
} else {
$menu_list = '<!-- no menu defined in location "'.$theme_location.'" -->';
}
return $menu_list;
}
Add this code to your menu page(header.php)
<?php echo create_bootstrap_menu('primary'); ?>
I'm wanting to add a button directly into the template. I'm using the starter theme Sage from roots with BS3. Here's my header
<header class="banner navbar navbar-default" role="banner">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only"><?= __('Toggle navigation', 'sage'); ?></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="logo navbar-brand" href="<?= esc_url(home_url('/')); ?>">
<img src="<?= get_template_directory_uri() . '/dist/images/logo.png'; ?>">
<img class="onwhite" src="<?= get_template_directory_uri() . '/dist/images/branding/logo.svg'; ?>">
</a>
</div>
<nav class="collapse navbar-collapse" role="navigation">
<?php
if (has_nav_menu('primary_navigation')) :
wp_nav_menu(['theme_location' => 'primary_navigation', 'walker' => new wp_bootstrap_navwalker(), 'menu_class' => 'nav navbar-nav']);
endif;
?>
</nav>
</div>
</header>
As you can see above, the ul and li's are dynamically generated by a customer walker class.
Walker
<?php
/**
* Class Name: wp_bootstrap_navwalker
* GitHub URI: https://github.com/twittem/wp-bootstrap-navwalker
* Description: A custom WordPress nav walker class to implement the Bootstrap 3 navigation style in a custom theme using the WordPress built in menu manager.
* Version: 2.0.4
* Author: Edward McIntyre - #twittem
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
*/
class wp_bootstrap_navwalker extends Walker_Nav_Menu {
/**
* #see Walker::start_lvl()
* #since 3.0.0
*
* #param string $output Passed by reference. Used to append additional content.
* #param int $depth Depth of page. Used for padding.
*/
public function start_lvl( &$output, $depth = 0, $args = array() ) {
$indent = str_repeat( "\t", $depth );
$output .= "\n$indent<ul role=\"menu\" class=\" dropdown-menu\">\n";
}
/**
* #see Walker::start_el()
* #since 3.0.0
*
* #param string $output Passed by reference. Used to append additional content.
* #param object $item Menu item data object.
* #param int $depth Depth of menu item. Used for padding.
* #param int $current_page Menu item ID.
* #param object $args
*/
public function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
/**
* Dividers, Headers or Disabled
* =============================
* Determine whether the item is a Divider, Header, Disabled or regular
* menu item. To prevent errors we use the strcasecmp() function to so a
* comparison that is not case sensitive. The strcasecmp() function returns
* a 0 if the strings are equal.
*/
if ( strcasecmp( $item->attr_title, 'divider' ) == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="divider">';
} else if ( strcasecmp( $item->title, 'divider') == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="divider">';
} else if ( strcasecmp( $item->attr_title, 'dropdown-header') == 0 && $depth === 1 ) {
$output .= $indent . '<li role="presentation" class="dropdown-header">' . esc_attr( $item->title );
} else if ( strcasecmp($item->attr_title, 'disabled' ) == 0 ) {
$output .= $indent . '<li role="presentation" class="disabled">' . esc_attr( $item->title ) . '';
} else {
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
$classes[] = 'menu-item-' . $item->ID;
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
if ( $args->has_children )
$class_names .= ' dropdown';
if ( in_array( 'current-menu-item', $classes ) )
$class_names .= ' active';
$class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';
$id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
$id = $id ? ' id="' . esc_attr( $id ) . '"' : '';
$output .= $indent . '<li' . $id . $value . $class_names .'>';
$atts = array();
$atts['title'] = ! empty( $item->title ) ? $item->title : '';
$atts['target'] = ! empty( $item->target ) ? $item->target : '';
$atts['rel'] = ! empty( $item->xfn ) ? $item->xfn : '';
// If item has_children add atts to a.
if ( $args->has_children && $depth === 0 ) {
$atts['href'] = '#';
$atts['data-toggle'] = 'dropdown';
$atts['class'] = 'dropdown-toggle';
$atts['aria-haspopup'] = 'true';
} else {
$atts['href'] = ! empty( $item->url ) ? $item->url : '';
}
$atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args );
$attributes = '';
foreach ( $atts as $attr => $value ) {
if ( ! empty( $value ) ) {
$value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
$attributes .= ' ' . $attr . '="' . $value . '"';
}
}
$item_output = $args->before;
/*
* Glyphicons
* ===========
* Since the the menu item is NOT a Divider or Header we check the see
* if there is a value in the attr_title property. If the attr_title
* property is NOT null we apply it as the class name for the glyphicon.
*/
if ( ! empty( $item->attr_title ) )
$item_output .= '<a'. $attributes .'><span class="glyphicon ' . esc_attr( $item->attr_title ) . '"></span> ';
else
$item_output .= '<a'. $attributes .'>';
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
$item_output .= ( $args->has_children && 0 === $depth ) ? ' <span class="caret"></span></a>' : '</a>';
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
}
}
/**
* Traverse elements to create list from elements.
*
* Display one element if the element doesn't have any children otherwise,
* display the element and its children. Will only traverse up to the max
* depth and no ignore elements under that depth.
*
* This method shouldn't be called directly, use the walk() method instead.
*
* #see Walker::start_el()
* #since 2.5.0
*
* #param object $element Data object
* #param array $children_elements List of elements to continue traversing.
* #param int $max_depth Max depth to traverse.
* #param int $depth Depth of current element.
* #param array $args
* #param string $output Passed by reference. Used to append additional content.
* #return null Null on failure with no changes to parameters.
*/
public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
if ( ! $element )
return;
$id_field = $this->db_fields['id'];
// Display this element.
if ( is_object( $args[0] ) )
$args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
/**
* Menu Fallback
* =============
* If this function is assigned to the wp_nav_menu's fallback_cb variable
* and a manu has not been assigned to the theme location in the WordPress
* menu manager the function with display nothing to a non-logged in user,
* and will add a link to the WordPress menu manager if logged in as an admin.
*
* #param array $args passed from the wp_nav_menu function.
*
*/
public static function fallback( $args ) {
if ( current_user_can( 'manage_options' ) ) {
extract( $args );
$fb_output = null;
if ( $container ) {
$fb_output = '<' . $container;
if ( $container_id )
$fb_output .= ' id="' . $container_id . '"';
if ( $container_class )
$fb_output .= ' class="' . $container_class . '"';
$fb_output .= '>';
}
$fb_output .= '<ul';
if ( $menu_id )
$fb_output .= ' id="' . $menu_id . '"';
if ( $menu_class )
$fb_output .= ' class="' . $menu_class . '"';
$fb_output .= '>';
$fb_output .= '<li>Add a menu</li>';
$fb_output .= '</ul>';
if ( $container )
$fb_output .= '</' . $container . '>';
echo $fb_output;
}
}
}
How can I inject a bootstrap navbar button in between the .navbar-collapse (encased in the dynamically generated <ul> </ul>)? I understand the fallback menu and how to add it there but not for the rest of the script above.
I do not wish to use the WP menu feature within wpadmin because it adds extra uneeded classes to the button and it breaks the css.
You could inject a new nav item using the 'wp_nav_menu_items' filter.
Assuming that you want to target your 'Primary Navigation' menu, add the following to Sage's /lib/extras.php:
add_action ('wp_nav_menu_items', function( $menu_items, $menu_object ){
$menu_name = $menu_object->menu->name;
// Only append the new li to the 'Primary Navigation' menu.
// Change 'Primary Navigation' for the name of the menu that you'd like to amend.
if ( 'Primary Navigation' === $menu_name ) {
$new_li = "<li><a class='btn btn-default' href='#'>The New Link</a></li>";
return $menu_items . $new_li;
}
return $menu_items;
}, 10, 2 );
You need to specify that '2' arguments should be passed to the callback, so that you can access the menu object for targeting purposes.
This method is limited (I think!) to appending or prepending <li>s to the menu.
I wanted to add number of posts for menu items that are categories.
For example:
Category 1 (5)
Category 2 (8)
Category 3 (2)
etc...
I edit walker:
get number:
$item_count = $depth == 0 ? get_posts( array(
'post_type' => 'post',
'numberposts' => -1,
'orderby' => 'category',
'order' => 'ASC'
) ) : false;
output:
$item_output .= $item_count ? ' <span>(' . count( $item_count ) . ')</span>' : '';
The result is a postscript to each menu item the number of all posts.
How to modify?
use wp_list_categories
<?php wp_list_categories(array('show_count' => true)); ?>
UPDATE for your instance:
with the full code from the link you provided in the comments we add an if statement right before the closing <a>
if($item->type == 'taxonomy'){
$cat = get_category( $item->object_id);
$item_output .= ' ('.$cat->count.')</a>';
}
FULL CODE:
/* Bootstrap_Walker for Wordpress
* Author: George Huger, Illuminati Karate, Inc
* More Info: http://illuminatikarate.com/blog/bootstrap-walker-for-wordpress
*
* Formats a Wordpress menu to be used as a Bootstrap dropdown menu (http://getbootstrap.com).
*
* Specifically, it makes these changes to the normal Wordpress menu output to support Bootstrap:
*
* - adds a 'dropdown' class to level-0 <li>'s which contain a dropdown
* - adds a 'dropdown-submenu' class to level-1 <li>'s which contain a dropdown
* - adds the 'dropdown-menu' class to level-1 and level-2 <ul>'s
*
* Supports menus up to 3 levels deep.
*
*/
class Bootstrap_Walker extends Walker_Nav_Menu
{
/* Start of the <ul>
*
* Note on $depth: Counterintuitively, $depth here means the "depth right before we start this menu".
* So basically add one to what you'd expect it to be
*/
function start_lvl(&$output, $depth)
{
$tabs = str_repeat("\t", $depth);
// If we are about to start the first submenu, we need to give it a dropdown-menu class
if ($depth == 0 || $depth == 1) { //really, level-1 or level-2, because $depth is misleading here (see note above)
$output .= "\n{$tabs}<ul class=\"dropdown-menu\">\n";
} else {
$output .= "\n{$tabs}<ul>\n";
}
return;
}
/* End of the <ul>
*
* Note on $depth: Counterintuitively, $depth here means the "depth right before we start this menu".
* So basically add one to what you'd expect it to be
*/
function end_lvl(&$output, $depth)
{
if ($depth == 0) { // This is actually the end of the level-1 submenu ($depth is misleading here too!)
// we don't have anything special for Bootstrap, so we'll just leave an HTML comment for now
$output .= '<!--.dropdown-->';
}
$tabs = str_repeat("\t", $depth);
$output .= "\n{$tabs}</ul>\n";
return;
}
/* Output the <li> and the containing <a>
* Note: $depth is "correct" at this level
*/
function start_el(&$output, $item, $depth, $args)
{
global $wp_query;
$indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
$class_names = $value = '';
$classes = empty( $item->classes ) ? array() : (array) $item->classes;
/* If this item has a dropdown menu, add the 'dropdown' class for Bootstrap */
if ($item->hasChildren) {
$classes[] = 'dropdown';
// level-1 menus also need the 'dropdown-submenu' class
if($depth == 1) {
$classes[] = 'dropdown-submenu';
}
}
/* This is the stock Wordpress code that builds the <li> with all of its attributes */
$class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
$class_names = ' class="' . esc_attr( $class_names ) . '"';
$output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
$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 ) .'"' : '';
$item_output = $args->before;
/* If this item has a dropdown menu, make clicking on this link toggle it */
if ($item->hasChildren && $depth == 0) {
$item_output .= '<a'. $attributes .' class="dropdown-toggle" data-toggle="dropdown">';
} else {
$item_output .= '<a'. $attributes .'>';
}
$item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
/* Output the actual caret for the user to click on to toggle the menu */
if ($item->hasChildren && $depth == 0) {
$item_output .= '<b class="caret"></b></a>';
}elseif($item->type == 'taxonomy'){
$cat = get_category( $item->object_id);
$item_output .= ' ('.$cat->count.')</a>';
} else {
$item_output .= '</a>';
}
$item_output .= $args->after;
$output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
return;
}
/* Close the <li>
* Note: the <a> is already closed
* Note 2: $depth is "correct" at this level
*/
function end_el (&$output, $item, $depth, $args)
{
$output .= '</li>';
return;
}
/* Add a 'hasChildren' property to the item
* Code from: http://wordpress.org/support/topic/how-do-i-know-if-a-menu-item-has-children-or-is-a-leaf#post-3139633
*/
function display_element ($element, &$children_elements, $max_depth, $depth = 0, $args, &$output)
{
// check whether this item has children, and set $item->hasChildren accordingly
$element->hasChildren = isset($children_elements[$element->ID]) && !empty($children_elements[$element->ID]);
// continue with normal behavior
return parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);
}
}
If you are using some custom post taxonomie you can change the code for this one :
if ($item->type == 'taxonomy'){
$term = get_term($item->object_id);
$item_output .= '<div class="meni-item-badge"> '.$term->count .'</div>';
}
Hope this help someone !!
Regards Mario