How to prevent parent admin page from appearring as a child admin page

I am using this code:

add_menu_page($page_title, $menu_title, $this->capability, $menu_slug, $function);

Which is adding top level admin page. When I add:

add_submenu_page( $menu_slug, 'sub menu 1', 'sub menu 1', $this->capability, $menu_slug . '_sub_menu_page_1', $function );

I get not only the desired child page, but also the parent page moves to become a child page of itself.

Solutions Collecting From Web of "How to prevent parent admin page from appearring as a child admin page"

Unless I misunderstand the question, this should do the trick:

add_action('admin_menu', 'add_menu_pages');

function add_menu_pages() {
    add_menu_page('Menu Title', 'Menu Title', 10, 'main_menu', 'submenu_1_callback');
    add_submenu_page('main_menu', 'Sub Menu Title 1', 'Sub Menu Title 1', 10,  'main_menu' , 'submenu_1_callback');
    add_submenu_page('main_menu', 'Sub Menu Title 2', 'Sub Menu Title 2', 10, 'sub_menu' , 'submenu_2_callback');
}

function submenu_1_callback() {
    echo "<h2>" . __( 'Toplevel & Sublevel 1', 'menu-test' ) . "</h2>";
}

function submenu_2_callback() {
    echo "<h2>" . __( 'Sublevel 2', 'menu-test' ) . "</h2>";
}

EDIT:

Here’s the easiest way to hide the first sub-menu item.

1) Create admin.css and move it to /[your template dir]/css/

2) Add this to your admin.css:

#adminmenu li#toplevel_page_main_menu li.wp-first-item {
    display: none !important;
}

3) Add the following code to your functions.php

add_action('admin_enqueue_scripts', 'custom_admin_css');
function custom_admin_css() {
    wp_enqueue_style( 'admin_css', (get_template_directory_uri() . '/css/admin.css'), false, '1.0.0' );
}

use remove_submenu_page() like this :

add_action('admin_menu','your_add_menu_function');
function your_add_menu_function() {
  add_menu_page('Menu Page Title','Menu Name','edit_theme_options/others caps...','parent_menu_slug',...);
  add_submenu_page('parent_menu_slug','Menu Page Title','Menu Name','...caps...','sub_menu_slug',...);
  add_submenu_page(...);
  remove_submenu_page('parent_menu_slug','parent_menu_slug'); // pay a attention
}

ok, parent_menu links to the first submenu page.

The standard trick is to repeat the main menu page as a submenu page, without the menu title (3rd parameter).

function add_menu_pages() {
    add_menu_page('Page Title', 'Menu Title', 'edit_posts', 'main_menu', 'menu_1_callback');
    add_submenu_page('main_menu', 'Page Title', '', 'edit_posts',  'main_menu' , 'menu_1_callback');
    add_submenu_page('main_menu', 'Page Title 1', 'Submenu Title 1', 'edit_posts',  'main_menu' , 'submenu_1_callback');
    add_submenu_page('main_menu', 'Page Title 2', 'Submenu Title 2', 'edit_posts', 'sub_menu' , 'submenu_2_callback');
}

That will give you

Menu Title
Submenu Title 1
Submenu Title 2

Is there some reason that you don’t just use remove_submenu_page() as applicable to remove the page being added, and then just build (or re-build, as the case may be) your menu structure?

But really, that would be a hack, and the need to use a hack is indicative of something doing wrong that needs to be fixed. For that, we’ll probably need the actual code being used.

add_action( ‘admin_menu’, ‘my_admin_menu’ );

function my_admin_menu() {
add_menu_page( ‘Optins’, ‘Theme Options’, ‘manage_options’, ‘options’, ‘options_admin_page’, ‘dashicons-admin-generic’, 6 );
add_submenu_page( ‘options’, ‘First Sub Options’, ‘First Option’, ‘manage_options’, ‘options’, ‘options_admin_sub_page_first’ );
add_submenu_page( ‘options’, ‘Second Sub Options’, ‘Second Option’, ‘manage_options’, ‘second-option’, ‘options_admin_sub_page_second’ );
}
function options_admin_page(){

}

function options_admin_sub_page_first(){

}

function options_admin_sub_page_second(){

}

Now you will get something like it, simple :)