Code: Getting rid of the duplicate submenu with add_menu_page and add_submenu_page

So  I ran across an issue today when creating a custom admin menu and submenu items. I wanted to have a submenu item in the menu that linked to the main admin menu page, but did not have the same anchor as the parent. I kept running into this:

 

You can see that, since I’m currently on the Options page, both the submenu item for “Program Areas” as well as the submenu item for “Options” are both saying they are active. That’s because this is the way you expect to create submenu pages:

<?php
// this is how you expect this to work:
public function add_options_page() {
$this->options_page = add_menu_page( __( 'Top Level Menu Title', 'add-menu' ), __( 'Top Level Menu', 'add-menu' ), 'manage_options', 'menu_slug', array( $this, 'admin_page_display' ), 'dashicons-star-filled', 12 );
$this->options_page = add_submenu_page( 'menu_slug', __( 'Menu Item 1', 'add-menu' ), __( 'Menu Item 1', 'add-menu' ), 'manage_options', 'menu_slug', array( $this, 'admin_page_display' );
$this->options_page = add_submenu_page( 'menu_slug', __( 'Menu Item 2', 'add-menu' ), __( 'Menu Item 2', 'add-menu' ), 'manage_options', 'a_different_menu_slug', array( $this, 'menu_item_2_function' ) );
}

view raw
add_menu_page.php
hosted with ❤ by GitHub

See? You declare the admin menu. Then you add the submenu. Makes sense, right? Everywhere you look, that’s how you will see it written. Even over here, where this guy was having the same problem.

But that will give you a submenu item with the first item in your submenu being a duplicate of your parent. There are even hacks where you create a menu item that’s just blank. So, great, here’s an empty tag in my menu. That’s a good solution, right? (Note, that didn’t work for me, either, but it did help in figuring out what did actually work.)

This is what you actually want to do if you want this:

 

<?php
// this is what ACTUALLY works
public function add_options_page() {
$this->options_page = add_submenu_page( 'menu_slug', __( 'Menu Item 1', 'add-menu' ), __( 'Menu Item 1', 'add-menu' ), 'manage_options', 'menu_slug', array( $this, 'admin_page_display' );
$this->options_page = add_submenu_page( 'menu_slug', __( 'Menu Item 2', 'add-menu' ), __( 'Menu Item 2', 'add-menu' ), 'manage_options', 'a_different_menu_slug', array( $this, 'menu_item_2_function' ) );
$this->options_page = add_menu_page( __( 'Top Level Menu Title', 'add-menu' ), __( 'Top Level Menu', 'add-menu' ), 'manage_options', 'menu_slug', array( $this, 'admin_page_display' ), 'dashicons-star-filled', 12 );
}

view raw
add_menu_page.php
hosted with ❤ by GitHub

See what I did there? I’m adding the submenu pages before the parent menu. For some reason, this short-circuits the tendency to create a submenu item with the same settings as the parent and allows me to have a submenu item with a different anchor link. This is the actual, working code from the project:

<?php
public function add_options_page() {
$this->options_page = add_submenu_page( self::$key, __( 'Edit Program Areas', 'nps' ), __( 'Edit Program Areas', 'nps' ), 'manage_options', 'edit-tags.php?taxonomy=career_center_interest' );
$this->options_page = add_submenu_page( self::$key, __( 'Program Areas Settings', 'nps' ), __( 'Options', 'nps' ), 'manage_options', self::$key, array( $this, 'admin_page_display' ) );
$this->options_page = add_menu_page( $this->title, __( 'Program Areas', 'nps' ), 'manage_options', self::$key, array( $this, 'admin_page_display' ), 'dashicons-star-filled', 12 );
}

view raw
add_menu_page.php
hosted with ❤ by GitHub

1 comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.