plugin development - Admin adding submenu that has the same destination as the parent menu

admin2025-05-31  0

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:

Share Improve this question edited May 23 at 7:27 La Fabrique Info asked May 21 at 14:42 La Fabrique InfoLa Fabrique Info 235 bronze badges 4
  • 1 edit your question to show the code you have tested. – mmm Commented May 21 at 16:15
  • It sounds like you're having the exact opposite problem that this user was having. Please edit your question to include your code, as mmm suggests. – Pat J Commented May 21 at 16:36
  • I still don't understand your question. you know that the problem is because there is no second sub menu and you write that you find a workaround for that then what is you actual issue ? and why do you want a sub-menu to only display one element and moreover the element is the same link that the menu item ? – mmm Commented May 23 at 6:54
  • Maybe I'm not clear, and I understand. My wish is only aesthetic, I like the look of having a "submenu" with different menu-title than his parent. Actually the "Google Site kit" plugin is doing it and I really like it. I haven't completely review all their code, but they are not using a css workaround but still, they achieve it. – La Fabrique Info Commented May 23 at 7:36
Add a comment  | 

2 Answers 2

Reset to default 1

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:

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1748626987a313624.html

最新回复(0)