Wordpress - Remove a menu item in menu

I think the best way to remove a menu item from a menu is by hooking to wp_nav_menu_objects filter (@Otto answer from the thread you mentioned). And the way you use is first check for the correct menu to filter, and then search for the menu item and remove it by unsetting it from the $sorted_menu_objects array.

This following example will remove the Uncategorized menu item from the menu that is on the secondary-menu theme location:

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

function ad_filter_menu($sorted_menu_objects, $args) {

    // check for the right menu to remove the menu item from
    // here we check for theme location of 'secondary-menu'
    // alternatively you can check for menu name ($args->menu == 'menu_name')
    if ($args->theme_location != 'secondary-menu')  
        return $sorted_menu_objects;

    // remove the menu item that has a title of 'Uncategorized'
    foreach ($sorted_menu_objects as $key => $menu_object) {

        // can also check for $menu_object->url for example
        // see all properties to test against:
        // print_r($menu_object); die();
        if ($menu_object->title == 'Uncategorized') {
            unset($sorted_menu_objects[$key]);
            break;
        }
    }

    return $sorted_menu_objects;
}

IT IS ACTUALLY WAAAY EASIER


Simple solution :

After several iterations with the wp_update_nav_menu_item function (see below) i just looked through the code to see what WP does itself in case an admin clicks on the "Delete" link of a menu entry.

Turns out that it simply calls wp_delete_post for that specific menu entry and that is that. Nothing else, nothing fancy. So in case you want to delete a menu entry, just get its db_id and call that function

wp_delete_post($menu_item_db_id);

 

For clarity I leave my former solutions here to assure you that nothing that sophisticated is really necessary:

 

DO NOT USE ONE OF THE FOLLOWING, NOW OBSOLETE, USE THE SIMPLE ONE FROM ABOVE


Version 1:

Adding (publishing) a menu entry is as easy as removing (unpublishing) it and can also be done with the same function.

I assume you used the scarcely documented wp_update_nav_menu_item function (see link for a post with an example) to add the menu entry programmatically and know how to call it, so to remove it you call the same function with the object id and the status unpublish

function removeMenuEntry($menu_id, $object_id, $menu_item_db_id) {
    $itemData = array(
        'menu-item-object-id' =>  $object_id,
        'menu-item-status' => 'unpublish'
    );
    return wp_update_nav_menu_item( $menu_id, $menu_item_db_id, $itemData );
}

$menu_id is the id of the menu the entry is in and $object_id the menu entries unique WP id which you know how to get as you said you already added an entry manually, if not refer to the link i gave for the wp_update_nav_menu_item function to see an example.

The code above will unpublish the entry which seems to be exactly what happens when you remove a menu entry via the admin panel.

Version 2:

Before i did not use $menu_item_db_id and just set that value to zero which worked fine for a menu entry that was of the 'menu-item-type' => 'taxonomy', but the same function did not work for a menu entry of type 'menu-item-type' => 'post_type'. After looking through the WP source just a little bit it seems that the fact that it worked without $menu_item_db_id being set is more an oversight and the correct way to do it is using it, as a zero value will create a new menu item (which it did in the latter case, obviously without title or anything).

The code example above has been updated and should work without problems now for taxonomy and post_type menu items.

Tags:

Menus