12

I know this has been asked many times. But from what i got after searching, i could not understand much. I have used wp_update_nav_menu_item to add menu items programatically. But i don't know how to remove a specific menu item. In one of the forums, it has been told to unset the array element (forum). But i did not understand it. Can anybody explain how to do it?

3 Answers 3

13

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;
}
3
  • Does this remove the menu item from the menu, or just prevents it from being rendered at that moment?
    – Larzan
    Commented Apr 7, 2014 at 12:25
  • 3
    This just temporarily filters the menu item from the menu. To permanently remove the menu item, see this answer.
    – rinogo
    Commented Jun 29, 2017 at 2:00
  • As has been said, this answer just HIDES the menu entry temporarily, to permanently DELETE it (analog to 'wp_update_nav_menu_item') use the answer below wordpress.stackexchange.com/a/140616/34517
    – Larzan
    Commented Jan 17, 2020 at 9:39
8

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.

2
  • 3
    Thank you thank you thank you! This really needs to be documented more widely. I see so many people advocating the "filter" approach. I'm happy to see that this is actually very straightforward. Faith in Wordpress restored! :)
    – rinogo
    Commented Jun 29, 2017 at 2:01
  • Your one line solution is so f******* smart. Thank you. Commented Jun 2, 2020 at 15:30
0

Useful answers here, for those of you who just want to 'Remove specific page ID from any menu', I've made a simple function:

/**
 * Removes a page from front-end menus by ID
 *
 * @param int id        WordPress Page ID
 *
 * @return int count of removed
 */
function zeroBSCRM_wp_removePageFromMenus($pageID=-1){

    // only if a valid $pageID
    if ($pageID > 0){

        // get menu locations
        $locations = get_nav_menu_locations();

        // cycle through (any) and get menu in slot
        if (is_array($locations)) foreach ($locations as $location => $menuID){

            // Retrieve Menu & Pages in menu
            $menu = wp_get_nav_menu_object($menuID);            
            $pagesItem = wp_get_nav_menu_items($menu, array("object"=>"page"));

            // Cycle through pages & remove target menu page link if present
            if (is_array($pagesItem)) 
              foreach ($pagesItem as $page)
                if ($page->object_id == $pageID) wp_delete_post($page->db_id);

        }

    }

    return 0;

}

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.