In a plugin I'm trying to to have a submenu which as the same destination as the parent.
Using add_menu_page
and add_submenu_page
with the same menu_slug
and no callback
for the parent menu. Just like it is said here :
But it doesn't work, I mean the submenu is not diplayed. I reckon it is cause of wp-admin/includes/menu.php:182
which remove submenus that have the same destination as their parent.
The workaround I've found, is to create second "dummy" submenu, and use css to hide this second submenu and also the parent which have a top-level submenu cause this dummy submenu.
EDIT : Actually I made a mistake, the top-level is not created if the dummy submenu is the last one added, so there only the last submenu to hide with css.
add_action('admin_menu', 'top_level_menu');
function top_level_menu()
{
$menu_slug = 'wpdocs-orders-slug';
add_menu_page(
'WP Docs Orders',
'WP Docs Orders',
'read',
$menu_slug,
false
);
add_submenu_page(
$menu_slug,
'Existing WP Docs Orders',
'Existing WP Docs Orders',
'read',
$menu_slug,
'wpdocs_orders_function'
);
add_submenu_page(
$menu_slug,
'Dummy',
'Dummy',
'read',
$menu_slug . '-dummy',
false
);
}
// Hiding the last submenu
add_action('admin_head', 'amdin_head_style');
function amdin_head_style()
{
echo "
<style>
#toplevel_page_wpdocs-orders-slug ul li:last-child{
display: none;
}
</style>
";
}
Any better idea?
Thanks
EDIT: 05/22/25
Here is the code used at the root of my plugin.
add_action('admin_menu', 'top_level_menu');
function top_level_menu() {
$menu_slug = 'wpdocs-orders-slug';
add_menu_page( 'WP Docs Orders', 'WP Docs Orders', 'read', $menu_slug, false );
add_submenu_page( $menu_slug, 'Existing WP Docs Orders', 'Existing WP Docs Orders', 'read', $menu_slug, 'wpdocs_orders_function' );
}
Here is what you get with this code:
Here is what I'm looking for:
In a plugin I'm trying to to have a submenu which as the same destination as the parent.
Using add_menu_page
and add_submenu_page
with the same menu_slug
and no callback
for the parent menu. Just like it is said here : https://developer.wordpress/reference/functions/add_menu_page/#comment-4771
But it doesn't work, I mean the submenu is not diplayed. I reckon it is cause of wp-admin/includes/menu.php:182
which remove submenus that have the same destination as their parent.
The workaround I've found, is to create second "dummy" submenu, and use css to hide this second submenu and also the parent which have a top-level submenu cause this dummy submenu.
EDIT : Actually I made a mistake, the top-level is not created if the dummy submenu is the last one added, so there only the last submenu to hide with css.
add_action('admin_menu', 'top_level_menu');
function top_level_menu()
{
$menu_slug = 'wpdocs-orders-slug';
add_menu_page(
'WP Docs Orders',
'WP Docs Orders',
'read',
$menu_slug,
false
);
add_submenu_page(
$menu_slug,
'Existing WP Docs Orders',
'Existing WP Docs Orders',
'read',
$menu_slug,
'wpdocs_orders_function'
);
add_submenu_page(
$menu_slug,
'Dummy',
'Dummy',
'read',
$menu_slug . '-dummy',
false
);
}
// Hiding the last submenu
add_action('admin_head', 'amdin_head_style');
function amdin_head_style()
{
echo "
<style>
#toplevel_page_wpdocs-orders-slug ul li:last-child{
display: none;
}
</style>
";
}
Any better idea?
Thanks
EDIT: 05/22/25
Here is the code used at the root of my plugin.
add_action('admin_menu', 'top_level_menu');
function top_level_menu() {
$menu_slug = 'wpdocs-orders-slug';
add_menu_page( 'WP Docs Orders', 'WP Docs Orders', 'read', $menu_slug, false );
add_submenu_page( $menu_slug, 'Existing WP Docs Orders', 'Existing WP Docs Orders', 'read', $menu_slug, 'wpdocs_orders_function' );
}
Here is what you get with this code:
Here is what I'm looking for:
the plugin Site Kit by Google plays with the capabilities to do that. you can see that in the source code here. this works actually with Wordpress 6.8.1 but it's not sure this trick will work with next versions.
to use the same trick in your code, you have to change the 2 parameters with comment in this code :
add_action('admin_menu', 'top_level_menu', 50);
function top_level_menu()
{
$menu_slug = 'wpdocs-orders-slug';
add_menu_page(
'WP Docs Orders'
, 'WP Docs Orders'
, 'do_not_allow' // this hides the first sub menu
, $menu_slug
, false
);
add_submenu_page(
$menu_slug
, 'Existing WP Docs Orders'
, 'Existing WP Docs Orders'
, 'read'
, "wpdocs_orders_function" // use a different slug than the parent
, 'wpdocs_orders_function'
);
}
It looks like the issue is that there's only one sub-menu page in your code. It seems like, if the menu page and the only sub-menu page share a slug, WordPress won't display the sub-menu.
Updating your code to this:
add_action('admin_menu', 'top_level_menu');
function top_level_menu() {
$menu_slug = 'wpdocs-orders-slug';
add_menu_page(
'WP Docs Orders',
'WP Docs Orders',
'read',
$menu_slug,
'__return_false'
);
add_submenu_page(
$menu_slug,
'Existing WP Docs Orders',
'Existing WP Docs Orders',
'read',
$menu_slug,
'wpdocs_orders_function'
);
add_submenu_page(
$menu_slug,
'New Existing WP Docs Orders',
'New Existing WP Docs Orders',
'read',
$menu_slug . '-new',
'wpdocs_orders_function'
);
}
... resulted in this: