Custom WordPress Admin Menu Pages

Today, while I was doing some work for Kyjen, I came across a situation that I wasn’t too sure how to handle: correctly utilizing the add_menu_page and add_submenu_page functions.

I couldn’t figure out how to have the first submenu item be a different name than the parent’s name. Let me clarify what I mean.

When you want to add a new menu item in the admin backend of WordPress, you call the function add_menu_page. It looks something like this:

add_menu_page( 'Plugin Home', 'Plugin Home', 0, 'myplugin_pagename', 'myplugin_functionname');

This results in a new menu item called “Plugin Home” that you can now click on that will call the myplugin_functionname() function that you’ve delcared in your plugin. In order to add items within your new menu, you’d simply use the add_submenu_item, like this:

add_submenu_page('myplugin_pagename', 'My Menu Item', 'My Menu item', 0, 'myplugin_mymenuitem', "myplugin_menuitemfunction");

You would expect to only see one menu item, right? We’ve only declared one submenu item, “My Menu Item”, so it should be pretty straight forward… Well it isn’t. You actually end up having two menu items: “Plugin Home” and “My Menu Item”.

I understand this default functionality; however, I didn’t want it with what I am doing. I couldn’t find anything that explained how to change the first item that is listed under a custom admin menu. Even changing the two string parameters in the add_menu_page doesn’t work, as the first parameter is for the page’s title that is displayed on the actual page and the second parameter is what shows up on the actual menu. Changing the second parameter ended up changing the header, as well as the menu item.

I was able to finally figure out what the hell was going on by guessing at what other plugins had done, even then it wasn’t exactly apparent (at least not to me.)

In order to replace that first menu item with different text, declare a submenu item that uses the same page name. For example:

// Add the menu header
add_menu_page( 'Plugin Home', 'Plugin Home', 0, 'myplugin_pagename', 'myplugin_functionname');

// Add the submenu item. Notice how they both use the myplugin_pagename page
add_submenu_page('myplugin_pagename', 'New Item Text', 'New Item Text', 0, 'myplugin_pagename', 'myplugin_menuitemfunction');

This caused me a bit of confusion, but let me know what you all think. Maybe there’s a more correct way of accomplishing this.