Skip to navigation | Skip to content



Customize the WordPress admin menus

NOTE: Forget these workarounds! We’ve now got core functions to do the trick :) Check out Justin Tadlock’s tutorial on using them.

Also, to disable theme and plugin editing, don’t just remove the menu links. You can use a constant in wp-config.php to completely switch that functionality off.

I’ve recently been looking at de-cluttering the WordPress admin interface. There’s some good plugins for this, such as Adminimize, WP-CMS Post Control (for hiding boxes on the post screen, according to user role) and White Label CMS (for extensive customization of logos, menus, etc.).

As ever, I’m also interested in getting just a particular aspect working with a bit of theme code—if only one aspect is needed, it’s sometimes nice to drop it into the theme and have one less plugin loading. The aspect I’m thinking of here is removing a few menu items.

So, with the usual caveat that this is code for theme developers, to be dropped into the active theme’s functions.php file, and a nod to hungred.com for initial inspiration, here goes.

The code is as follows:

// Customize menus
function slt_customizeAdminMenus() {
	// Remove theme / plugin editors
	slt_removeSubmenu( 'themes.php', 'theme-editor.php' );
	slt_removeSubmenu( 'plugins.php', 'plugin-editor.php' );
	// Remove comments / categories / tags
	slt_removeMenu( 'edit-comments.php' );
	slt_removeSubmenu( 'edit.php', 'edit-tags.php?taxonomy=category' );
	slt_removeSubmenu( 'edit.php', 'edit-tags.php?taxonomy=post_tag' );
}
add_action( 'admin_head', 'slt_customizeAdminMenus' );

// Remove item from a submenu
function slt_removeSubmenu( $parentMenuItem, $item ) {
	global $submenu;
	//mail( "your@email.address", "$submenu", print_r( $submenu, true ) );
	foreach ( $submenu as $menuKey => $menuItem ) {
		if ( $menuKey == $parentMenuItem ) {
			foreach ( $menuItem as $submenuKey => $submenuItems ) {
				if ( $submenuItems[2] == $item ) {
					unset( $submenu[$menuKey][$submenuKey] );
					break;
				}
			}
		}
	}
}

// Remove item from the main menu
function slt_removeMenu( $item ) {
	global $menu;
	//mail( "your@email.address", "$menu", print_r( $menu, true ) );
	foreach ( $menu as $menuKey => $menuItem ) {
		if ( $menuItem[2] == $item ) {
			unset( $menu[$menuKey] );
			break;
		}
	}
}

The first function is added to the admin_head hook, to modify the arrays that have been set up containing the menu items remove the appropriate menus. If you’re curious, you can uncomment those two lines of mail() code in the other functions, and insert your email address—load a WP admin page and you should get two emails showing the contents of these global menu arrays. The way the rest of the above code works will then be much clearer.

So, basically the two following functions are there to remove specified items—either submenu items or entire top-level items. The first function just calls them as appropriate. My main two removals are getting rid of the Theme and Plugin Editor links—I never use these and never really want clients to use them. There’s also lines to remove the Categories, Tags, and Comments stuff. In my own themes, I have settings to globally turn these on or off, and these lines remove each item only if it’s been disabled. You can comment out / leave in whichever lines are appropriate, depending on what WP features your site uses.

Please note that this code does not disable or block the use of these features. People logged into WP, with the right permissions, could in theory type in the URL to, say, the Plugin Editor, and use it as normal. All the above is doing is tidying the menus up to give clients less unnecessary clutter.

Anyway, have fun with the code, and please post any suggestions here!

UPDATE 18/8/10: Improved code based on Mathias’ suggestion, to modify $menu and $submenu global variables within the second two functions themselves.

20 comments

  1. Rich (12th August 2010)

    Nice code. Clean. But can you give an example using the //Remove item from main menu, please? For example, removing the main ‘links’ menu. I just can’t quite figure out which part of the code to change to specify which menu I want removed.

  2. Steve Taylor (13th August 2010)

    Line 10 removes the comments menu. If you check the post I referred to for this, you’ll see a dump of the arrays that contain the menus. You should be able to figure anything else out from that. Though actually, it may be as simple as checking the page that the menu links to. As you can see from line 10, the item argument passed to slt_removeMenu is “edit-comments.php”—just the page that the comments menu links to. Following that logic should help, too.

  3. Mathias (18th August 2010)

    What do you think of doing it this way:

    http://gist.github.com/533713

    This makes it even simpler by placing the call to the global $submenu and $menu variables inside slt_removeMenu() and slt_removeSubmenu. This way you don’t need to pass them as a function parameter nor redefine them for each removed item.

    By the way, thanks for your code. : )

    /charge

  4. Mathias (18th August 2010)

    Just realized that you don’t need to call the global $menu variable inside slt_removeSubmenu(). Just calling global $submenu is fine (line 19).

  5. Steve Taylor (18th August 2010)

    Mathias, you’re probably right – seems like a better-contained way of doing this. I’ll update the code above when I get a minute! Thanks.

  6. Shonda (26th August 2010)

    I’m about to edit the functions.php file, but exactly where should I put the code you are suggesting? At the top or at the bottom? Does it matter? I do not have any experience with PHP. Thanks.

  7. Steve Taylor (26th August 2010)

    Shonda, it doesn’t matter where in the file it goes—just make sure you understand the basics of WordPress theme development and the fact that it’s the theme’s functions.php that you have to edit. Some people mistakenly edit the file in wp-includes (bad idea!).

  8. Shonda (28th August 2010)

    Hello Again… The code is working, because it’s mailing information to me, but there aren’t any changes taking place. I’m running 3.0.1 (Multisite – only 1 additional site that does not belong to the SuperAdmin) – do you think I need to do something different?

  9. Steve Taylor (28th August 2010)

    Shonda, I’ve not tested this code on a multisite system, but on the other hand I’m not sure why it wouldn’t work.

    Maybe you’re better off with one of the plugins mentioned at the start of the post?

  10. Rich (28th August 2010)

    I couldn’t get this to work either (3.0, Thematic theme). But for whatever reason, the github code worked a-okay.

  11. Steve Taylor (28th August 2010)

    Shonda, Rich, everyone else, apologies. It seems a couple of typos have crept into the code, specifically at lines 21 and 35. The unset statements weren’t referencing the right arrays! It’s corrected now, should work :)

  12. Shonda (28th August 2010)

    Thank you! It’s working!

  13. Frank Torres (17th February 2011)

    Fantastic! WordPress has a lot more menu options than the average client looking for a CMS needs or wants. This makes it easier to streamline the admin and strip out tools that could inadvertently be used break the theme. Thank you!!

  14. Peter (13th April 2011)

    Hey Steve, good job! Any ideas on how to remove the post_tag submenu from a custom post type menu? Something like:

    slt_removeSubmenu( 'edit.php', 'edit-tags.php?taxonomy=post_tag&post_type=myproduct );

    doesn’t seem to do the trick.

  15. Steve Taylor (13th April 2011)

    Hi Peter, not sure about that one. Let me know if you crack it!

  16. Huroman (28th April 2011)

    Hi, is it possible to unset/disable some categories from the admin (adminroot/edit-tags.php?taxonomy=category)?

    Thank you.

  17. Steve Taylor (28th April 2011)

    @Huroman, I’m not sure. Have a go! ;-)

  18. Huroman (28th April 2011)

    Ok, never mind, i realized how to using:
    if($terms[$key]->term_id == 7){unset($terms[$key]);}

    but i have another question, is it possible to unset it (the cagetory) in post.php (categorydiv, the postbox)?

    Thank you.

  19. Steve Taylor (13th July 2011)

    Hi to anyone subscribed to the comments here. Please check out the new notices I’ve added at the top of the post! Topic now closed :)

Comments on this post are closed.

Recent posts

View complete archives »