Web DevelopmentWordPress

How to get the second level navigation only from WordPress wp_nav_menu()

By February 28, 2015 7 Comments
How to get the second level navigation only from WordPress wp_nav_menu()

We’ve all been there. There’s a perfectly good menu in the admin under Appearance -> Menus which has the whole site laid out perfectly.

Now we start coding the templates and realize that we only need sub-menu items of a particular page, of a particular level from that menu. There are two ways to do this out of the box:

  1. Create a separate menu for each requirement
  2. Create a custom Walker Class which allows you to only choose only the sub-menu from the main menu

For obvious reasons, the first option is not the best way to do it. The second option solves the problem quite well. But you can’t keep writing a walker class for every project, and not every developer – particularly new developers – is familiar with how this works.

This should be something that comes out of the box, which it does on other platforms like Joomla. When you delve into the code of WordPress and see the function responsible for this ( /wp-includes/nav-menu-template.php :: wp_nav_menu() ), you quickly realize that this function was written without any foresight for extendability.

I have solved this problem of extending this function by writing a plugin!
https://wordpress.org/plugins/wp-nav-menu-extended/

It extends the native wp_nav_menu function so you don’t need to add any special functions to the code. It just adds a few options that I felt were missing. Here are the options:

level : (integer) (required for this plugin to work) The level of the navigation menu to show. If no child_of parameter is passed, it shows all the items of this level

child_of : (string|integer) (optional) Either the title or menu item ID of the parent in the menu whose direct children are to be shown

This is how easy it is to use:

$defaults = array(
    'theme_location' => 'main_menu',
    'level' => 2,
    'child_of' => 'About Us'
);

wp_nav_menu( $defaults );

So, the child_of option can either be the title of the parent’s menu item, or the menu item ID of the parent, so that you don’t have to hardcore the title in the code. Here is one easy way to find the menu item ID:

Hover your mouse on top of the menu item that you want, and look for the item ID in the status bar. In this case it is 466.

I hope this makes it easy for you to build your site! I’ll be open to adding more features to this plugin, so feel free to write in any feature requests in the comments.

Happy coding!

7 Comments

  • Sachin G Kulkarni says:

    Your post helped me to finish one of my client work. So thanks for taking time to share this resource.

    By the by do you accept guest post. I write on various topics in my blog

  • arne says:

    Hi,

    where should I insert the Code?

    $defaults = array(
    ‘theme_location’ => ‘main_menu’,
    ‘level’ => 2,
    ‘child_of’ => ‘About Us’
    );

    wp_nav_menu( $defaults );

    Looking forward to hear from you.
    Greetings!

  • Charlotte says:

    Hello,

    Thanks for the plugin! The plugin is working, but the order menu is alphabetical, not showing in the order that I specified in Appearance > Menus.

    Any additional code to add so the specified order is respected?

    Thanks!

  • Tomasz says:

    THANKS!

  • Anders says:

    Hey! I have a navigation that uses “&”… that causes problem with the comparison with the get_menu_id_from_title function.
    You should use html_entity_decode when comparing if the provided “name” is equal to one of the items in the nav.

    I solved it with:

    if ( html_entity_decode($item->title) == html_entity_decode($name) )
    return $item->ID;

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.