Wordpress - how do I know if a menu item has children?
It seems that the problem has finally been addressed. The latest Wordpress beta as of current writing 4.0, has updated the Walker_Nav_Menu class and added a $has_children
property.
/**
* Whether the current element has children or not.
*
* To be used in start_el().
*
* @since 4.0.0
* @access protected
* @var bool
*/
protected $has_children;
So, we don't need to hack function display_element(...)
anymore.
Add this to functions.php
it will add the 'dropdown' class to parents
New way beter for performance
function menu_set_dropdown( $sorted_menu_items, $args ) {
$last_top = 0;
foreach ( $sorted_menu_items as $key => $obj ) {
// it is a top lv item?
if ( 0 == $obj->menu_item_parent ) {
// set the key of the parent
$last_top = $key;
} else {
$sorted_menu_items[$last_top]->classes['dropdown'] = 'dropdown';
}
}
return $sorted_menu_items;
}
add_filter( 'wp_nav_menu_objects', 'menu_set_dropdown', 10, 2 );
Old: intensive on the DB
add_filter( 'nav_menu_css_class', 'check_for_submenu', 10, 2);
function check_for_submenu($classes, $item) {
global $wpdb;
$has_children = $wpdb->get_var("SELECT COUNT(meta_id) FROM wp_postmeta WHERE meta_key='_menu_item_menu_item_parent' AND meta_value='".$item->ID."'");
if ($has_children > 0) array_push($classes,'dropdown'); // add the class dropdown to the current list
return $classes;
}
Simple you use this way:
Explain: I create menu with "walker":
$walker = new Nav_Walker;
wp_nav_menu(array(
'container'=>'nav',
'container_class'=>'menu',
'menu_class'=>'list-unstyled list-inline',
'walker'=>$walker
));
Class Walker:
class Nav_Walker extends Walker_Nav_Menu
{
public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0)
{
if($args->walker->has_children)
{
//code...
}
}
}
We have object 'walker', you can var_dump($args) to see more things. I'm using for my project !