I am trying to customize the admin area using the functions.php file to make things easier for my clients. One request I have got before and hope to be able to accomplish, is to move some of the sub menus into the main navigation.

For instance I would like to make Widgets and Menus appear in the main navigation as opposed to being a submenu for Appearances. I would then end up removing the Appearances tab all together.

I have been able to remove the tab but unable to make the new buttons for Widgets and Menus. Even if I can get help of not technically moving them but instead creating a new button and setting the link myself (ex. for Menus -> /nav-menus.php).

Is any of that possible?


  • 1
    Mike once wrote a great menu API layer, perhaps the functions you need are already included there?
    – Jan Fabry
    Feb 13, 2011 at 16:52
  • @Jan: Wow! A great link and a good read. Even if this doesn't make it into 3.1, this is an excellent tool. Feb 13, 2011 at 20:14

6 Answers 6


OK, it's a bit messy, but it works. Take a look

function remove_submenus() {
  global $submenu;
  unset($submenu['themes.php'][10]); // Removes Menu  
add_action('admin_menu', 'remove_submenus');

function new_nav_menu () {
    global $menu;
    $menu[99] = array('', 'read', 'separator', '', 'menu-top menu-nav');
    add_menu_page(__('Nav Menus', 'mav-menus'), __('Nav Menus', 'nav-menus'), 'edit_themes', 'nav-menus.php', '', 99);
add_action('admin_menu', 'new_nav_menu');

Essentially it is removing the nav menu settings from the Appearance sub-panel, then re-adding it as a top level page (similar to a plugin). You can set an icon URL in there as well. The only part I can't get working the way I want is the positioning.


As for Wordpress 4.4 I have to use following code to make it work:

function adjust_admin_menu() {
  global $menu;

  remove_submenu_page( 'themes.php', 'nav-menus.php' );

  // Add nav menu as top element
  $menu[31] = array( __( 'Menus', 'theme-slug' ), 'edit_theme_options', 'nav-menus.php', __( 'Menus', 'theme-slug' ), 'menu-top menu-nav', 'menu-nav', 'dashicons-menu');  
add_action( 'admin_menu', 'adjust_admin_menu' );
  • Still works perfectly in Wordpress 5.6. But the "design" sub menu stays open, as it still sees the menu page as a subpage of the menu.
    – rank
    Jan 23, 2021 at 14:43

You can change the order by using the menu_order filter:

function custom_menu_order($menu_ord) {  
if (!$menu_ord) return true;  

return array(  
    'index.php', // Dashboard  
    'edit.php', // Posts 
    'upload.php', // Media
    'edit.php?post_type=page', // Pages
    'edit-comments.php', // Comments 
    'link-manager.php', // Links 
    'separator1', // First separator  
    'nav-menus.php', // Navigation
    'separator2', // Second separator  
    'themes.php', // Appearance  
    'plugins.php', // Plugins  
    'users.php', // Users  
    'tools.php', // Tools  
    'options-general.php', // Settings  
    'separator-last', // Last separator  
add_filter('custom_menu_order', 'custom_menu_order'); // Activate custom_menu_order  
add_filter('menu_order', 'custom_menu_order');

This was taken from this article here: customizing your wordpress admin

Notice that the nav-menu.php has been added to the top level menu. To re-position each menu item just rearrange them.

  • Have you tested this code? Ain't working on my side... WordPress 3.4.2 and 3.5-beta2
    – brasofilo
    Oct 20, 2012 at 2:46

Good article on this, old link that can help with this, http://wpengineer.com/475/top-level-menu-in-wordpress-27/

Also, the solution that @Norcross is proposing works great, but the icon 99 will throw an error, you could leave it blank, eg. '' instead of 99. You could also have your own custom icon using basename(__FILE__) and the filename.


It's even simpler if, like the OP, you only want to move Menus and Widgets out of Appearance and to the top level. That's what I needed too.

Since we're just moving WP core menu items around, we don't need to use add_menu_page to add the menu items back in - we're not adding any new menu items. Just unset them from the $submenu array and re-set them elsewhere in the $menu array.

function re_sort_menu() {
  global $menu;
  global $submenu;
  // Note: find the position of every submenu in Appearance by uncommenting the following: 
  // print_r($submenu['themes.php'];
  unset($submenu['themes.php'][10]); // Unsets Appearance -> Menu (position 10)
  unset($submenu['themes.php'][7]); // Unsets Appearance -> Widgets

  // Add Menu and Widgets back at top level with some dashicons
  // Be careful not to give menu positions (array keys) that conflict with other menu items
  // TIP: print_r($menu); to see existing menu positions and also to check out the proper order of these array values. WP docu seems to list them in the incorrect order.
  $menu[31] = array( __( 'Menus', 'theme-slug' ), 'edit_themes', 'nav-menus.php', __( 'Menus', 'theme-slug' ), 'menu-top menu-nav', 'menu-nav', 'dashicons-menu');  
  $menu[32] = array( __( 'Widgets', 'theme-slug' ), 'edit_themes', 'widgets.php', __( 'Widgets', 'theme-slug' ), 'menu-top menu-nav', 'menu-nav', 'dashicons-admin-generic');  
add_action( 'admin_menu', 're_sort_menu' );

Norcross's answer above put me on the right track, but for whatever reason using add_menu_item did not regenerate a working "Nav Menu" section as a top level menu item in the admin for me in WP 4.1. The problem seemed to lie in the order of the array values passed to that function, but no matter how I reordered things, working straight off the new WP Developer API article, i never got it working.

add_action( 'admin_menu', 'dashboard_remove_menu_pages' );
function dashboard_remove_menu_pages() {
     remove_submenu_page( 'themes.php', 'nav-menus.php' );
     add_menu_page('Menu', 'Menu', 'edit_themes', 'nav-menus.php', '' , 'dashicons-menu', 3);

this should work. also with the positioning. in this case menu position: 3. just abide to wordpress struktur:

add_menu_page( string $page_title, string $menu_title, string $capability, string $menu_slug, callable $function = '', string $icon_url = '', int $position = null )
  • 1
    That doesn't actually achieve the objective of removing the Themes menu and is also not so different to the other longstanding answers on this question. Jul 25, 2016 at 15:05
  • well it works for me.. and true it is nothing new but it fixes the problem with the positioning. so ne need to vote negative ;) Aug 11, 2016 at 10:36

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.