How to remove admin menu pages inserted by plugins?

I’ve got the following code, which cleans up a lot of stuff that is not going to be used within the admin area:

add_action( 'admin_menu', 'my_remove_menu_pages' );

function my_remove_menu_pages() {
  remove_menu_page( 'edit.php' );                   //Posts
  remove_menu_page( 'upload.php' );                 //Media
  remove_menu_page( 'edit-comments.php' );          //Comments
  remove_menu_page( 'themes.php' );                 //Appearance
  remove_menu_page( 'users.php' );                  //Users
  remove_menu_page( 'tools.php' );                  //Tools
  remove_menu_page( 'options-general.php' );        //Settings

};

However, there are two menu items that have been inserted from plugins.

Read More

When I hover over each menu item, it says the links are:

/wp-admin/edit.php?post_type=acf
/wp-admin/admin.php?page=wpcf7

Is there a way to hide these menu pages, too?

Related posts

7 comments

  1. You need to use the right hooks (which are not always the same as the URLs/slugs), and it doesn’t hurt to use a hook that runs later (e.g., admin_init):

    add_action( 'admin_init', 'wpse_136058_remove_menu_pages' );
    
    function wpse_136058_remove_menu_pages() {
    
        remove_menu_page( 'edit.php?post_type=acf' );
        remove_menu_page( 'wpcf7' );
    }
    

    You can use the following to debug:

    add_action( 'admin_init', 'wpse_136058_debug_admin_menu' );
    
    function wpse_136058_debug_admin_menu() {
    
        echo '<pre>' . print_r( $GLOBALS[ 'menu' ], TRUE) . '</pre>';
    }
    

    This gives (for my setup) the following for the Contact Form 7 plugin menu page:

    [27] => Array
            (
                [0] => Formular
                [1] => wpcf7_read_contact_forms
                [2] => wpcf7
                [3] => Contact Form 7
                [4] => menu-top menu-icon-generic toplevel_page_wpcf7 menu-top-last
                [5] => toplevel_page_wpcf7
                [6] => none
            )
    

    The array element with key 2 is what you are looking for: wpcf7.

  2.     // PLUGINS THAT ADD AS DASHBOARD SUBMENU
        // IF THIS IS THE URL BELOW - THE PAGE VARIABLE IS WHAT I NEED ( SO WHATEVER COMES AFTER PAGE= )
        // http://example.com/wp-admin/index.php?page=iconize-plugin-update-notifier
        remove_submenu_page( 'index.php', 'iconize-plugin-update-notifier' );
    
        // OR FOR EXAMPLE WOOCOMMERCE DASHBOARD SUBMENU
        remove_submenu_page( 'index.php', 'wc-about' ); //WOO
        remove_submenu_page( 'index.php', 'wc-credits' ); //WOO
        remove_submenu_page( 'index.php', 'wc-translators' ); //WOO
    
        // CUSTOM POST TYPE TOP LEVELS
        remove_menu_page( 'edit.php?post_type={$POST_TYPE}' ); //LOOK FOR WHAT COMES AFTER POST TYPE IN THE URL
        remove_menu_page( 'edit.php?post_type=testimonials-widget' ); //TESTIMONIALS WIDGET
        remove_menu_page( 'edit.php?post_type=product' ); //WOOCOMMERCE
    
        // CUSTOM POST TYPE SUBMENU
         remove_submenu_page( 'edit.php?post_type={$POST_TYPE}', '{$SUBMENU_URL_VARIABLE}' ); //EXAMPLE FORMAT
         // SO IF BELOW IS THE URL
         // http://example.com/wp-admin/edit.php?post_type=testimonials-widget&page=testimonialswidget_settings
         // YOU NEED TO SEE WHATS AFTER PAGE
         remove_submenu_page( 'edit.php?post_type=testimonials-widget', 'testimonialswidget_settings' ); //TESTIMONIALS WIDGET
    
        // OTHER EXAMPLES
        remove_menu_page( 'revslider' ); // REVSLIDER
        remove_menu_page( 'woocommerce' ); // WOOCOMMERCE
        remove_menu_page( 'order-post-types-shop_order' ); // WOOCOMMERCE
        remove_menu_page( 'order-post-types-shop_coupons' ); // WOOCOMMERCE
        remove_menu_page( 'shortcodes-ultimate' ); // SHORTCODES ULTIMATE
        remove_menu_page( 'wp-admin-microblog/wp-admin-microblog.php' ); // ADMIN MICROBLOG
        remove_menu_page( 'snippets' ); //CODE SNIPPETS
        remove_menu_page( 'gf_edit_forms' ); // GRAVITY FORMS
            remove_submenu_page( 'gf_edit_forms', 'gf_settings' ); // GRAVITY FORMS
            remove_submenu_page( 'gf_edit_forms', 'gf_export' ); // GRAVITY FORMS
            remove_submenu_page( 'gf_edit_forms', 'gf_update' ); // GRAVITY FORMS
            remove_submenu_page( 'gf_edit_forms', 'gf_addons' ); // GRAVITY FORMS
            remove_submenu_page( 'gf_edit_forms', 'gf_help' ); // GRAVITY FORMS
    
            remove_submenu_page( 'cleverness-to-do-list', 'cleverness-to-do-list-settings' ); //Cleverness TODO
    

    YOU CAN DEBUG ALL THIS WITH THE FOLLOWING TO GET ALL THE INFO YOU NEED:

    if (!function_exists('debug_admin_menus')):
    function debug_admin_menus() {
    if ( !is_admin())
            return;
        global $submenu, $menu, $pagenow;
        if ( current_user_can('manage_options') ) { // ONLY DO THIS FOR ADMIN
            if( $pagenow == 'index.php' ) {  // PRINTS ON DASHBOARD
                echo '<pre>'; print_r( $menu ); echo '</pre>'; // TOP LEVEL MENUS
                echo '<pre>'; print_r( $submenu ); echo '</pre>'; // SUBMENUS
            }
        }
    }
    add_action( 'admin_notices', 'debug_admin_menus' );
    endif;
    

    The keys will give you the array values that allow you do all of this with wordpress globals (although not recommended)

    function remove_submenus_all_please() {
    if ( !is_admin())
            return;
      global $submenu;
        unset($submenu['index.php'][10]); // Removes Updates
      //Posts menu
     // unset($submenu['edit.php'][5]); // Leads to listing of available posts to edit
     // unset($submenu['edit.php'][10]); // Add new post
     // unset($submenu['edit.php'][15]); // Remove categories
     // unset($submenu['edit.php'][16]); // Removes Post Tags
    }
    add_action('admin_menu', 'remove_submenus_all_please', 999);
    

    And to remove for certain users just do the same thing except with capabilities added:

    function remove_by_caps_admin_menu() {
    if ( !is_admin())
            return;
        if ( !current_user_can('manage_options') ) {
            remove_menu_page( 'revslider' ); // REVSLIDER
        } elseif ( !current_user_can('edit_posts') ) {
            remove_menu_page( 'woocommerce' ); // WOO
        } else {
        }
    }
    add_action('admin_menu', 'remove_by_caps_admin_menu', 999);
    

    AND TO TIE IT ALL TOGETHER WHY NOT SHORTEN OUR CODE? YOU CAN USE ARRAYS TO AVOID WRITING remove_submenu_page 50 times. This also works with the toolbar nodes:

    if ( !function_exists( 'remove_admin_menupages_in_array' ) ) {
    function remove_admin_menupages_in_array() {
        if ( !is_admin())
            return;
              $admin_menus = array(
                                    'revslider',
                                    'woocommerce',
                                    'shortcodes-ultimate',
              );
    
        foreach ( $admin_menus as $menu_page ) {
            if ( !current_user_can('manage_options') ) {
                remove_menu_page( $menu_page );
            }
        } // foreach
     } // function
    add_action('admin_menu', 'remove_admin_menupages_in_array', 9999);
    } // exists
    
  3. You probably need to set the add_action priority to a higher number and target those two new links specifically like so:

    add_action( 'admin_menu', 'my_remove_menu_pages', 999 );
    
    function my_remove_menu_pages() {
      remove_menu_page( 'edit.php' );                   //Posts
      remove_menu_page( 'upload.php' );                 //Media
      remove_menu_page( 'edit-comments.php' );          //Comments
      remove_menu_page( 'themes.php' );                 //Appearance
      remove_menu_page( 'users.php' );                  //Users
      remove_menu_page( 'tools.php' );                  //Tools
      remove_menu_page( 'options-general.php' );        //Settings
      remove_menu_page( 'edit.php?post_type=acf' );
      remove_menu_page( 'wpcf7' );
    };
    

    Advanced Custom Fields also provides a help document on how to do this for their menu here:

    http://www.advancedcustomfields.com/resources/how-to/how-to-hide-acf-menu-from-clients/

    Contact Form 7 also has it’s own way of restricting the visibility of the menu:

    http://contactform7.com/restricting-access-to-the-administration-panel/

  4. Update

    I created a code snippet with a more robust function that deals with both main menus and sub-menu items.

    Original answer

    Instead of specifying the menus you want to remove, specify the menues you want to keep 🙂

    add_action('admin_init', 'nwcm_admin_init');
    
    function nwcm_admin_init()
    {   
        // Remove unnecessary menus 
        $menus_to_stay = array(
            // Client manager
            'nwcm',
    
            // Dashboard
            'index.php',
    
            // Users
            'users.php'
        );      
        foreach ($GLOBALS['menu'] as $key => $value) {          
            if (!in_array($value[2], $menus_to_stay)) remove_menu_page($value[2]);
        }   
    
    } 
    

    This way you don’t have to search for plugin names and modify the code when you add new plugins..

  5. You need to find the right $menu_slug. The following code worked for me:

    add_action( 'admin_init', 'remove_menus' );
    function remove_menus(){
      remove_menu_page( 'wpcf7' );
    }
    
  6. Of course you can specify only the items you want to remove. Have a look in the code below:

    /wordpress/wp-content/plugins/your_plugin/your_plugin.php :
    
    
    add_action('admin_init', 'nwcm_admin_init');
    
    function nwcm_admin_init()
    {   
    // Remove unnecessary menus 
    $menus_to_remove = array(
        // menu items you want to remove
        'menu_item_1',
        'menu_item_2',
        .
        .
        'menu_item_n'
    );     
    
    // To avoid warning message, check whether 'menu' is set AND is an array
    if(isset($GLOBALS['menu']) && is_array($GLOBALS['menu'])) {
       foreach ($GLOBALS['menu'] as $key => $value) {  
         //Remove the '!' in the 'if' condition.        
         if (in_array($value[2], $menus_to_remove)) remove_menu_page($value[2]);
       }
    }   
    
    } 
    

    This is just the negative of numediaweb’s method. Thanks @numediaweb. It works fine.

    P.S.:
    ‘menu_item_1/n’ -> point mouse over the menu item and fetch the exact page of that menu item shown in the link.

  7. use this code snippet

    function your_custom_name() {    
        remove_menu_page('vc-general'); //the slug as seen wp-admin.php?page=vc-general  
    }    
    add_action( 'admin_init', 'your_custom_name' );
    

Comments are closed.