0

i'm working on the new site with custom menu and extended Walker_Nav_Menu class to add custom content to the wp nav menu.

i have registered a custom select box (key: my_custom_menu) in menu from wordpress admin, have a look at the following image:

https://i.sstatic.net/JYb9u.jpg

My question is: Is there any way to remove/exclude the submenu if the user use custom menu instead of multilevel submenu, example:

//conditional for parent menu item Contact us
if($menu_item->my_custom_menu !== 'none'){

    //Remove all the nested submenu with depth != 0 (including <ul class="submenu">)
    // so the expecting result is : remove all submenus inside Contact us .

}

i know there's a function called display_element() in Walker class but i dont know how to use it.

4
  • You can also filter wp_get_nav_menu_items to remove items from the menu, which integrates better with themes that might have their own custom walkers. I did that for my Nav Menu Roles plugin. I don't have time to write a full answer, but maybe the source code will help you. Commented Mar 10, 2013 at 18:03
  • Thanks for the suggestion, i did use the filter wp_get_nav_menu_items to unset menu items, but this way removed menu items from both admin backend and frontend. Also i tried to skip item from start_el() and end_el() but it slowdown the performance
    – MaxxDinh
    Commented Mar 10, 2013 at 18:33
  • Just wrap whatever you are doing in a !is_admin() conditional to avoid any deleterious effects on the admin side of things. Commented Mar 11, 2013 at 13:41
  • Yes, i know that, both wp_get_nav_menu_items and wp_nav_menu_objects optimized the performance but i'm still stuck in the loops to get all the child menu items by menu parent ID.
    – MaxxDinh
    Commented Mar 11, 2013 at 14:06

2 Answers 2

1

Filter 'wp_nav_menu_objects' would help:

add_filter( 'wp_nav_menu_objects', 'remove_sub_items', 10, 2 );
function remove_sub_items( $items,$args ) {
    $new_items = array();
    for ($i=1;$i<count($items)+1;$i++){

        //is lvl0
        if(empty($items[$i]->menu_item_parent)){
           $new_items= array_merge($new_items, nav_tree($items[$i],$items));
        }

    } 
  // var_dump($new_items); die();
    if( $args->theme_location == 'primary' )
        return $new_items; 
    return $items;   
}

function nav_tree($parent,$items){
      $rtn = array();
      $rtn[] = $parent;
      //Edit this conditional, return menu level 0 if has custom menu
      if($parent->my_custom_menu && $parent->my_custom_menu !== 'none') return $rtn;
      for ($i=1;$i<count($items)+1;$i++){
         if($items[$i]->menu_item_parent && $items[$i]->menu_item_parent == $parent->ID)
        {
            $rtn= array_merge($rtn,nav_tree($items[$i],$items));

        }

      }
      return $rtn;
}
6
  • Please add a short explanation to your answer and thus help the reader to understand your answer more easily.
    – tfrommen
    Commented Mar 11, 2013 at 8:22
  • Thanks Lê Phan Đức Trọng, it works, but the Sidebar Tabs item now jump to depth 0, that means it work only on depth 1. BTW, is there a way to apply this filter to specified menu by detecting the theme_location? and one more thing: the $item child count from 1 so we need change $items[$i] to $items[$i+1].
    – MaxxDinh
    Commented Mar 11, 2013 at 9:46
  • i got the theme_location via $args : if( $args->theme_location == 'primary' )
    – MaxxDinh
    Commented Mar 11, 2013 at 10:20
  • Maxx ! Checkout new code. Commented Mar 11, 2013 at 12:53
  • Still doesn't work, it removes all the submenus in another menu parents that not custom menu .
    – MaxxDinh
    Commented Mar 11, 2013 at 13:45
0

Just the nested menu at depth 2, 3, 4 ... to go, any idea to modify the loops ? i have modified the above code to:

add_filter( 'wp_nav_menu_objects', 'remove_sub_items', 10, 2 );
function remove_sub_items( $items,$args ) {
    $new_items = array();
    for ($i=1;$i<count($items)+1;$i++){

        //is child
        if($items[$i]->menu_item_parent && $items[$i]->menu_item_parent != 0)
        {
            for ($j=1;$j<count($items)+1;$j++){
                if($items[$j]->ID == $items[$i]->menu_item_parent && $items[$j]->my_custom_menu == 'none'){
                    $new_items[]=$items[$i];   
                }
            }
        }
        else{
            $new_items[]=$items[$i];
        }

    } 
    //var_dump($new_items); die();
    if( $args->theme_location == 'primary-menu-nav' )
        return $new_items; 
    return $items;   
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.