How to remove/hide elements from the admin menu?

The question:

I would like to hide Pages and Comments from the editor.

I tried to override them with my custom types’ menu_position but it doesn’t work in WordPress 3.7.1 any more.

I found another way: removing the entries from admin menu by altering the global $menu variable on menu_order filter. Unfortunately it produces errors in menu.php: array_flip() gets passed a null.

I’m guessing that WordPress assumes that default values are still there.

Is there some way of filtering the menu entries when they are rendered?
Even better: is there a way of setting the default post types public option to false?

class RemoveAdminMenuItems {

 * List of values used for key identification
 * @var array
public $remove_keys = array();

 * List of values used for key identification. Identified keys will be removed.
 * @param array $remove_keys
public function __construct($remove_keys)

    $this->remove_keys = $remove_keys;

    add_filter( 'custom_menu_order', '__return_true' );
    add_filter( 'menu_order', array($this, 'reconstruct_menu'));


 * Method modifies the admin menu before it gets rendered.
 * @global array $menu
public function reconstruct_menu() {

    global $menu;

    foreach ($menu as $menu_key => $menu_value) {
        foreach ($this->remove_keys as $remove_key) {
            $key = array_search($remove_key, $menu_value);
            if ($key) {



The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

If you just want to hide the menu items, you can do it like shown below. Don’t forget about the entries inside the admin bar.


//hide in admin menu
add_action( 'admin_menu', 'wpse121406_hide_pages_comments_m' );
function wpse121406_hide_pages_comments_m() {
    remove_menu_page( 'edit-comments.php' );

//hide in admin bar
add_action( 'wp_before_admin_bar_render', 'wpse121406_hide_pages_comments_b' );
function wpse121406_hide_pages_comments_b() {
    global $wp_admin_bar;

But you have to keep in mind that this doesn’t disable/restrict the functionality. The edit pages and the comments page can still be reached by typing in the address into the location bar. If you want to restrict access by user type you have to go with Roles and Capabilities.


Regarding your second question, on how to alter the built in post types properties. You can achieve this by going at it like shown below. You can use the registered_post_type or the init hook and can either use get_post_type_object() or the global $wp_post_types.


function wpse121406_alter_post_type_object() {
  $object = get_post_type_object('page');
  $object->public = false;

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment