Remove a menu item in menu

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?

Related posts

Leave a Reply

3 comments

  1. 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;
    }
    
  2. 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.

  3. 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;
    
    }