Display a portion/ branch of the menu tree using wp_nav_menu()

I have a menu defined in WP Admin that looks like this:

alt text

I want to be able to display all the child links on the sidebar whenever I am at a parent page. For example, if the user is on my “About Us” page, I want a list of the 4 links highlighted in green to appear on the sidebar.

I looked at the documentation for wp_nav_menu() and it doesn’t appear to have any built-in way to specify a particular node of a given menu to use as the starting point when generating the links.

I created a solution for a similar situation which relied on the relationships created by the page parent, but I am looking for one which uses the menu system specifically. Any help would be appreciated.

This was still on my mind so I revisited it and put together this solution, that does not rely on context that much:

add_filter( 'wp_nav_menu_objects', 'submenu_limit', 10, 2 );

function submenu_limit( $items, $args ) {

    if ( empty( $args->submenu ) ) {
        return $items;
    }

    $ids       = wp_filter_object_list( $items, array( 'title' => $args->submenu ), 'and', 'ID' );
    $parent_id = array_pop( $ids );
    $children  = submenu_get_children_ids( $parent_id, $items );

    foreach ( $items as $key => $item ) {

        if ( ! in_array( $item->ID, $children ) ) {
            unset( $items[$key] );
        }
    }

    return $items;
}

function submenu_get_children_ids( $id, $items ) {

    $ids = wp_filter_object_list( $items, array( 'menu_item_parent' => $id ), 'and', 'ID' );

    foreach ( $ids as $id ) {

        $ids = array_merge( $ids, submenu_get_children_ids( $id, $items ) );
    }

    return $ids;
}

Usage

$args = array(
    'theme_location' => 'slug-of-the-menu', // the one used on register_nav_menus
    'submenu' => 'About Us', // could be used __() for translations
);

wp_nav_menu( $args );

Leave a Comment