I have the following code:

add_filter( 'wp_nav_menu_objects', 'dynamically_add_shop_categories_to_submenu' );
function dynamically_add_shop_categories_to_submenu( $items ) {        
    $taxonomy_name = array( 
    $args = array(
        'orderby'    => 'name', 
        'order'      => 'ASC',
        'hide_empty' => true, 
        'fields'     => 'all', 
        'exclude'    => '160',
    $terms = get_terms( $taxonomy_name, $args );
    $base = 'http://' . $_SERVER['HTTP_HOST'] . '/businesses/';
    $bc = '&shop-category=';
    $bt = '?business-type=shops';             
    foreach ( $terms as $term ) {
        $shops = array (
            'title'            => $term->name,
            'menu_item_parent' => 1157,
            'ID'               => '',
            'db_id'            => '',
            'url'              => $base . $bt . $bc . $term->slug
        $items[] = (object) $shops;
    return $items;    

This successfully adds submenu items from the 'shop-category' taxonomy to a top level menu with the ID 1157. This works as expected.

There are more top level menus which remain unaffected by this, which is correct, as we've only specified these items to be added to the 1157 menu.

However, at the footer of our site we have three more menus, all of which get these submenus added. Why is the code doing that? The menus don't appear to have any IDs, so how do we modify the code to exclude them?

1 Answer 1


You can use the second input argument $args to target the specific menu.

Here's an example with some checks that you can adjust to your needs:

add_filter( 'wp_nav_menu_objects', function( $sorted_menu_items, $args )
           'primary' === $args->theme_location   // Alternative
        && 'some_menu_slug' === $args->menu->slug  // Alternative
    ) {
        // Your stuff here ...
    return $sorted_menu_items;
}, 10, 2 );

When we add a menu item, a new row is created in the wp_posts table. This is the ID you're referring to. When we delete it and add it again, then we will get a new ID. So it might be better to target the menu theme location or the menu slug instead.

When you append the custom menu items in your example and the menu_item_parent doesn't exists, in the current menu, then it should be added to the menu as an item with menu_item_parent = 0.

  • Thanks for this. What is the purpose of the "menu_item_parent" value in our example code above then? I thought this is what targets the menu, as it does in the first instance. But also targets other menus without given ID's.
    – pixelkicks
    Commented Dec 24, 2015 at 15:47
  • I updated the answer with an array vs object fix on $args. I don't think it's enough to have a non existent menu_item_parent to prevent the menu item to display in the current menu. You could give an example how you call these nav menus. @Buckers
    – birgire
    Commented Dec 25, 2015 at 13:24
  • 1
    Works great. I also referenced the code from @Foxinni at wordpress.stackexchange.com/questions/15455/…. Thanks.
    – pixelkicks
    Commented Dec 31, 2015 at 10:34
  • You're welcome, glad to hear you could use it, looks like Foxinni is using the wp_nav_menu_items filter, but you the wp_nav_menu_objects filter @suprtickets
    – birgire
    Commented Dec 31, 2015 at 10:49

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.