When it comes to defining custom option pages, theme pages, menu pages, and submenu pages, the provided API makes this trivially easy; however, one of the less used aspects of these functions is the ability to define a custom WordPress menu hook.

For example, in a recent project I needed to do exactly that when adding a submenu to the WordPress Tools menu so I thought I’d share my process for doing exactly this.

Note that if you’re looking to add a submenu to a different WordPress menu, then there are a couple of options that are available. First and foremost, the most common option is to use add_submenu_page and then use tools.php as the parent slug as specified in the Codex.

But if you happen to be working with the Tools menu, then the add_management_page function is your best bet because it’s designed for exactly that.

So for this article, that’s what I’ll be using.

A Custom WordPress Menu Hook

For what it’s worth, I rarely add anything to the Tools menu, but in a recent project I’ve been working on a plugin that is responsible for importing a set of data and that menu is arguably the best place for the plugin’s menu.

After all, the plugin is providing a tool to the end user and although I need a custom hook that’s available, it’s not using the WordPress Settings API. If that were the case, then I’d be taking an entirely different approach (and then writing an entirely different post :)).

Adding a Submenu To The Tools Menu

First, take a look at the Codex article for the add_management_page function. If you’re familiar with any of the other menu functions, then this should be really easy to understand.

The function accepts five arguments:

  1. The text to be displayed in the browser’s tab or title bar
  2. The text to be displayed in the sub menu item
  3. The required capability to access the menu item
  4. The slug required to uniquely identify this page
  5. The name of a function callback for rendering the page associated with the menu item

A practical example would look something like this:

add_action( 'admin_menu', 'add_data_import_menu' );
function add_data_import_menu() {

	add_management_page(
		'Import Data',
		'Import Data',
		'manage_options',
		'data-importer',
		'display_import_page'
	);

}

function display_import_page() {
    // Note that this is where the code for the display of the custom page would exist
}

Easy enough, but there’s a subtle nuance to this particular function that not all submenu functions offer: This function will return the slug associated with the menu item (so, in this case, data-importer) that we can then use as a custom hook.

Custom Hooks Provided By The Management Page

Note that any hooks that are associated with the Tools page will be prefixed the tools_page_ and then suffixed with the ID returned from add_management_page.

So, for example, the hook that will be available for our new menu item will be tools_page_data-importer. This then allows us to introduce our own hook:

add_action( 'tools_page_data-importer', 'custom_data_importer_hook' );

At this point, you’d implement the custom_data_importer_hook function just like you would for any other hook.

And This is Just For The Tools Menu?

Remember that this particular example is more of a practical example that’s come from some work I’ve been doing. Check out the Page Hook Suffixes and you’ll see that it’s not limited to the Tools menu.

In fact, they are available for any of the “add page” functions. Good news, right?

The thing is, I’m not sure that this is one of those things that’s immediately clear to WordPress developers that haven’t spent a significant amount of time in the Codex. I’m not sure what this says about me, but I wasn’t familiar with this until recently and it wasn’t until this week that I actually implemented it in an actual project (that is, beyond toying around with it).

So if you find yourself needing a custom hook for an options page, submenu page, theme page, or any other custom page, then perhaps defining a custom WordPress menu hook is what you need.