WordPress.org

Ready to get started?Download WordPress

Forums

wp_nav_menu: List only 2nd level (separate submenu)? (54 posts)

  1. danieliser
    Member
    Posted 3 years ago #

    I have tried all the custom walker classes ive found on the net including these and havnnt had luck at getting it to successfully not display children of unactive parent items. i did come up with this function though that will return what the correct menu. Not sure if it will be of any help to anybody but here it is.

    [Code moderated as per the Forum Rules. Please use the pastebin]

  2. dikkevandale
    Member
    Posted 3 years ago #

    XGhozt:

    Anyone know of any of the scripts here allow me to only display the sub menu of a specific parent menu? For example, if there's 3 menu item's, home, about, contact..

    Let's say there's 5 sub menu links under "about".

    How can I use wp_nav_menu to only display the items under the "about" menu item?

    I have exact the same question. My menu is also separated in 2 menus:
    1: Horizontal menu with main pages
    2. Horizontal menu with subpages thats located somewhere else in my theme.

    What I want to achieve is use wp_nav_menu on 2 different places in my theme:
    1. Include wp_nav_menu (show only main items).
    2. Include wp_nav_menu (show only sub items belonging to the current main item).

  3. jonkristian
    Member
    Posted 3 years ago #

    This is pretty cool, hopefully something similar will be included in a future release of WP. But, what about pages/categories that doesn't have any children, the menu is still printed...

    EDIT: There are also a couple of other problems with the initial modification, the li id is included and it outputs an empty ul before the initial list, the empty ul only happens on pages that doesn't have children though, so we're back to my first paragraph. :)

  4. archiparmentier
    Member
    Posted 3 years ago #

    How to use wp_nav_menu to display the children of a page when she has?

    If using get_pages we will have a table that will return the "guid" page, type http://monsite.com//?page_id=2
    We can extract the id
    here id = 2
    with get_permalink(id) we have the URLs of pages,
    from get_pages so we can create an array containing the URLs of pages

    in "class description_walker" we can be retrieved item-> url

    we verified that item_> url is in the list of URLs of pages (in array)
    If it is
    if (get_permalink ('2 ') == item-> url)
    we verified that the page has children
    if she has children, we display the submenu pages-Children

    I am very bad at English and I do not know code! but I try to participate :-)

    -------------------

    Comment utiliser wp_nav_menu pour qu'il affiche les enfants d'une page quand elle en a ?

    Si on utilise get_pages on aura un tableau qui retournera le "guid" de la page, du type http://monsite.com//?page_id=2
    On peut en extraire l'identifiant
    ici : id=2
    avec get_permalink(id) on obtient les urls des pages donc à partir de get_pages on peut créer un tableau contenant les urls des pages

    dans class description_walker on peut récupérer item->url

    on verifie que item_>url est dans le tableau des urls de pages (in array)
    Si c'est le cas
    if (get_permalink('2')==item->url)
    on verifie que la page a des enfants
    si elle a des enfants on affiche le sous-menu des pages-enfants

    Je suis très mauvais en anglais et je ne sais pas coder ! mais j'essaye de participer :-)

  5. Kovas
    Member
    Posted 3 years ago #

    Well, I did it with CSS.

    First, you need to output whole wp_nav_menu.
    Then hide all menu links with:

    #menu-name a {
    	display: none;
    }

    Then display only children of current menu:

    #menu-name .current-menu-item li a, #menu-name .current-menu-ancestor li a {
    	display: block;
    }

    And finaly - do styling on #menu-name .sub-menu for container and #menu-name li a for menu links - this way, in case when there're no children, you won't have an empty block.

  6. Kovas
    Member
    Posted 3 years ago #

    Well, it works fine when you have pages, but there's a problem with posts.
    When i'm in a post of a category, WordPress decides, that I don't need .current-menu-ancestor classes anymore, so only thing I can get is a link back to current category (I want to display whole upper level, not just current parent).

  7. squarecandy
    Member
    Posted 3 years ago #

    I'm using sushicoder's original solution, as posted by petersom3000, with nerdfactor's revision to eliminate the parent item.
    Works like a charm. THANK YOU to everyone who helped with this...

    Just to sum it all up:

    1) Put this in your functions.php file:

    [Code moderated as per the Forum Rules. Please use the pastebin]

  8. squarecandy
    Member
    Posted 3 years ago #

    This is so close to being perfect - check out my implementation of the above code here:
    http://toomaiquintet.com/bios/

    Only one tiny little problem:

    <ul id="menu-menu-1" class="sister-pages">
    <ul class="sub-menu">
    	<li ...
    	<li ...
    </ul>
    </li>
    </ul>

    Anyone know how to add <li> after <ul id="menu-menu-1" class="sister-pages"> using this custom walker code? Not a huge deal - it still works as is, but it would be nice to have proper HTML.

  9. 5ulo
    Member
    Posted 3 years ago #

    squarecandy thanks for this code. Works perfectly. But when i turned WP Debug mode ON, there was an error, that says:
    Notice: Undefined variable: item_output in /home/enjoy/www/enjoy/ubytovanie/wp-content/themes/ubytovanie/functions.php on line 536
    The 536th line was
    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    So i moved this line at the end of the 'if' statement above, so it looks now like this

    [Code moderated as per the Forum Rules. Please use the pastebin]

    The error disappeared and everything works fine.

  10. squarecandy
    Member
    Posted 3 years ago #

    UPDATE:
    This version of the function fixes the missing <li> and integrates 5ulo's bug fix.

    1) Put this in your functions.php file:

    [Code moderated as per the Forum Rules. Please use the pastebin]

    2) Put this in your theme file, like sidebar.php or wherever else you might want to put your submenu:

    $menu_args = array(
      'walker'          => new Custom_Walker_Nav_Sub_Menu(),
      'container'       => '',
      'menu_class'      => 'sister-pages',
    );
    wp_nav_menu($menu_args);

    3) Make sure you have some custom CSS to style it all up.

    Also note that with the new menu system you can add multiple instances of a single page the the menu. That's very handy - for example I've added a top level menu item "About" to this menu, and then added "About" again as its first subpage, but renamed the link "About the Quintet".
    http://toomaiquintet.com/bios/

    Fun times with menus!

  11. squarecandy
    Member
    Posted 3 years ago #

    Dag - automated code-chunk removal - that's new!
    New Function here:
    http://wordpress.pastebin.com/Jk7n20mB

  12. becskr
    Member
    Posted 3 years ago #

    Hi Squarecandy, tried your updated code but not seeing the correction for the missing <li> tag. Wouldn't it also be more correct to remove the additional <ul> rather than adding an <li> to contain it?

  13. squarecandy
    Member
    Posted 3 years ago #

    Hey becskr -

    I've got valid html with that code at the toomai link above. Do you have a link to your implementation?

    I agree - it would be best to just have one level of unordered list rendered... but we're hacking at the menu walker code that would normally show the top level and secondary menu items to just show the secondary level - so I'm not sure if/how that's possible...

  14. becskr
    Member
    Posted 3 years ago #

    I can't show you as I'm just running it on localhost - I've realised what the problem is but not how to resolve it. The issue's with the top level menu not having a class of "current-menu-parent" on the current category.

    Could you give me your function for your primary walker please? That'd be really helpful!

    Thanks :)

  15. squarecandy
    Member
    Posted 3 years ago #

  16. becskr
    Member
    Posted 3 years ago #

    OK cool thanks! I have got it to work, but it means having to put the parent category as a sub menu category as well. If you take it away, the parent category no longer has current-menu-parent class so doesn't add the additional <li>

  17. becskr
    Member
    Posted 3 years ago #

    Of course, the solution would be to hide that child category if you didn't want it to show, meaning that the current-menu-parent class would still show on the parent.

  18. dantdr
    Member
    Posted 3 years ago #

    Hey there, this walker works great, i just wanted to ask if there is any way you could help me to modify it a bit. I am kind of new and i can't seem to make this work, i'm trying to get this to work for two days now.

    I want the walker to only show the current submenu, so i have :

    Parent 1
    - Child 1
    - Child 2
    Parent 2
    - Child 3
    - Child 4
    - Child 5
    Parent 3
    - Child 6

    Now if i am on the page Child 1, i see Parent 2's Childs, and i want it to be like this, when i'm on Parent 1`s childs the menu to show:

    Parent 1
    - Child 1
    - Child 2
    Parent 2
    Parent 3

    When i'm on Parent 2's childs the menu to show:

    Parent 1
    Parent 2
    - Child 3
    - Child 4
    - Child 5
    Parent 3

    And so on. Is this possible? if it is, could you at least give me a hint or something towards the right way?

    Thank you

  19. squarecandy
    Member
    Posted 3 years ago #

    dantdr -
    Sounds like you're not quite in the right place w/ this thread.
    Try rendering the whole menu with the regular wp_nav_menu function and then hiding what you don't want to see w/ some CSS.

    ul.sub-menu {display:none;}
    li.current-menu-ancestor ul.sub-menu {display:block;}

    something like that.

  20. dantdr
    Member
    Posted 3 years ago #

    i just managed to do what i needed with the help of danieliser`s function, thanks

  21. jevets
    Member
    Posted 3 years ago #

    Another subnav walker that seems to work well in a few quick tests:
    http://pastebin.com/Hxnf3WWb

    Found via
    http://wpquestions.com/question/show/id/1522

  22. vonkanehoffen
    Member
    Posted 3 years ago #

    Here's a walker I made to just display child menu items of the current top level one (even if they're a few deep). Not perfect (it still shows empty

  23. jevets
    Member
    Posted 3 years ago #

    Also, the Gecka Submenu (http://wordpress.org/extend/plugins/gecka-submenu/) plugin works well.

  24. Ziccu
    Member
    Posted 3 years ago #

    Hi all,

    this works for me:

    on wp-includes/classes.php row 860

    change from
    if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) )

    to
    if ( ($max_depth == 0 || $max_depth >= $depth+1 ) && isset( $children_elements[$id]) )

    obviously creating a custom walker duplicating
    the function "display_element" containing the modified code in order to avoid editing the core...

    here it is:

    class Custom_Walker_Nav_Sub_Menu extends Walker_Nav_Menu {
    
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
    
      if ( !$element )
       return;
    
      $id_field = $this->db_fields['id'];
    
      //display this element
      if ( is_array( $args[0] ) )
       $args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
      $cb_args = array_merge( array(&$output, $element, $depth), $args);
      call_user_func_array(array(&$this, 'start_el'), $cb_args);
    
      $id = $element->$id_field;
    
      // descend only when the depth is right and there are childrens for this element
      if ( ($max_depth == 0 || $max_depth >= $depth+1 ) && isset( $children_elements[$id]) ) {
    
       foreach( $children_elements[ $id ] as $child ){
    
        if ( !isset($newlevel) ) {
         $newlevel = true;
         //start the child delimiter
         $cb_args = array_merge( array(&$output, $depth), $args);
         call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
        }
        $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
       }
       unset( $children_elements[ $id ] );
      }
    
      if ( isset($newlevel) && $newlevel ){
       //end the child delimiter
       $cb_args = array_merge( array(&$output, $depth), $args);
       call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
      }
    
      //end this element
      $cb_args = array_merge( array(&$output, $element, $depth), $args);
      call_user_func_array(array(&$this, 'end_el'), $cb_args);
     }
    }

Topic Closed

This topic has been closed to new replies.

About this Topic