remove_submenu_page( string $menu_slug, string $submenu_slug ): array|false

Removes an admin submenu.

Description

Example usage:

  • remove_submenu_page( 'themes.php', 'nav-menus.php' )
  • remove_submenu_page( 'tools.php', 'plugin_submenu_slug' )
  • remove_submenu_page( 'plugin_menu_slug', 'plugin_submenu_slug' )

Parameters

$menu_slugstringrequired
The slug for the parent menu.
$submenu_slugstringrequired
The slug of the submenu.

Return

array|false The removed submenu on success, false if not found.

More Information

Depending on when this function is called, it may not prevent users from accessing the screen for the removed submenu directly (see ticket #18850). Removing a menu does not replace the need to filter a user’s permissions as appropriate.

In order to remove the theme-editor.php submenu of themes.php (and others) in more recent versions of WordPress, you need to bind to the admin_menu hook with a very high priority (about 110, depending on the submenus to remove). Don’t use admin_init as previously stated here, hence it will break wp-admin/admin-ajax.php.

Source

function remove_submenu_page( $menu_slug, $submenu_slug ) {
	global $submenu;

	if ( ! isset( $submenu[ $menu_slug ] ) ) {
		return false;
	}

	foreach ( $submenu[ $menu_slug ] as $i => $item ) {
		if ( $submenu_slug === $item[2] ) {
			unset( $submenu[ $menu_slug ][ $i ] );
			return $item;
		}
	}

	return false;
}

Changelog

VersionDescription
3.1.0Introduced.

User Contributed Notes

  1. Skip to note 5 content

    Sometimes it can be tricky to figure what combination of menu/submemiu slug is required to remove a submenu.

    You can figure it out by actually printing the global $submenu array to your debug.log file, and identifying the submenu you want to remove.

     global $submenu;
     error_log(print_r($submenu, true)); //this will print out all the menus/submenus currently available in the admin.
  2. Skip to note 6 content

    Reference: Administration Menus

    MENU.................KEY...LINK URL
    Dashboard.............2.....index.php
    -Home.................0.....index.php
    Separator (first).....4.....separator1
    Posts.................5.....edit.php
    -All Posts............5.....edit.php
    -Add New..............10....post-new.php
    -Categories...........15....edit-tags.php?taxonomy=category
    -Tags.................16....edit-tags.php?taxonomy=post_tag
    Media.................10....upload.php
    -Library..............5.....upload.php
    -Add New..............10....media-new
    Links.................15....link-manager.php
    -All Links............5.....link-manager.php
    -Add New..............10....link-add.php
    -Link Categories......15....edit-tags.php?taxonomy=link_category
    Pages.................20....edit.php?post_type=page
    -All Pages............5.....edit.php?post_type=page
    -Add New..............10....post-new.php?post_type=page
    Comments..............25....edit-comments.php
    -All Comments.........0.....edit-comments.php
    Separator (Second)....59....separator2
    Appearance............60....themes.php
    -Themes...............5.....themes.php
    -Widgets..............7.....widgets.php
    -Menus................10....nav-menus.php
    Plugins...............65....plugins.php
    -Installed Plugins....5.....plugins.php
    -Add New..............10....plugin-install.php
    -Editor...............15....plugin-editor.php
    Users.................70....users.php
    -All Users............5.....users.php
    -Add New..............10....user-new.php
    -Your Profile.........15....profile.php
    Tools.................75....tools.php
    -Available Tools......5.....tools.php
    -Import...............10....import.php
    -Exports..............15....export.php
    Settings..............80....options-general.php
    -General..............10....options-general.php
    -Writing..............15....options-writing.php
    -Reading..............20....options-reading.php
    -Discussion...........25....options-discussion.php
    -Media................30....options-media.php
    -Privacy..............35....options-privacy.php
    -Permalinks...........40....options-permalink.php
    Separator (last)......99....separator-last

    Source: Matt Whiteley

  3. Skip to note 7 content

    Example
    Removes the Widgets submenu page.

    /**
     * Remove the Widgets submenu page.
     */
    function wpdocs_adjust_the_wp_menu() {
    	$page = remove_submenu_page( 'themes.php', 'widgets.php' );
    	// $page[0] is the menu title
    	// $page[1] is the minimum level or capability required
    	// $page[2] is the URL to the item's file
    }
    add_action( 'admin_menu', 'wpdocs_adjust_the_wp_menu', 999 );

    In the above example, the value of $page would have been:

    array(3) { [0]=> string(7) "Widgets" [1]=> string(18) "edit_theme_options" [2]=> string(11) "widgets.php" }
  4. Skip to note 8 content

    The submenu slug may be HTML-encoded. Some automatically generated submenu slugs contain multiple query parameters. For example, if one adds categories to a custom post type “video”, the submenu slug will be edit-tags.php?taxonomy=category&post_type=video.

    This is stored in the $submenu array entry as edit-tags.php?taxonomy=category&post_type=video.

    You must pass the encoded version to remove_submenu_page(), or else it will not find a match.

    You can handle this programmatically by using htmlspecialchars() on your submenu slugs before calling this function. Consider setting the double_encode parameter to false if there’s any chance your string will have been encoded already.

    (This is a pain to debug in the browser, since HTML entities get rendered! Use XDebug or a server-side log to ensure you see the true slug values in $submenu)

You must log in before being able to contribute a note or feedback.