If you are familiar with the WordPress admin, you probably noticed the “Help” tab at the top right of nearly every screen. Clicking this little gem reveals a series of helpful topics related to the current page. For example, on the Dashboard, the tab offers an overview of what’s currently displayed, how to navigate the admin in general and what the different boxes on the screen do. This information is invaluable to a new user of WordPress and stays politely out of the way for the more experienced.

Wouldn’t it be neat if your plugin admin or custom post type screens implemented their own help tabs? Of course it would! And it’s rather simple too. Let’s jump in with a simple implementation! If you’re antsy and just want to skip ahead, check out the gist.

Implementing Custom Help Tabs

Let’s begin with two custom pages on the admin: a post type edit screen and a settings menu. Somewhere in our functions.php or plugin file(s) …

All help tabs should be specified in the load-{filename} action and require the current instance of the WP_Screen class for the page we want to enhance. Specifically, we will be calling the WP_Screen#add_help_tab() and WP_Screen#set_help_sidebar() methods. Looking at the book edit screen, the filename is either post-new.php (for a new book) or post.php (for editing an existing one). The settings page “filename” is returned from the call to add_options_page(). For the sake of brevity, we are going to assume that we want to add the same help tabs to each of these pages. The following changes should be made to the code above:

First, we add the load-{filename} action hooks to the book-type registration and settings page methods. For the setting page, notice we capture the unique $page identifier returned from add_options_page() and used it to build the action key. All three hooks callback to our new cjr_add_help_tabs() function to add the tabs.

In cjr_add_help_tabs(), the current instance of WP_Screen is obtained via get_current_screen(). The $tabs array contains the arguments for generating each of our help tabs. These tabs require a 'title' and a unique 'id'.

Next, we provided the content for the tabs in a couple of ways. The first is using 'content' which is just a string of HTML, which is useful if the text is short, not updated frequently and doesn’t require any dynamic – well – content. The other method is to include a 'callback' function (as in the second tab with cjr_get_more_tab()) that handles outputting the content. This is particularly useful if our help content is long or includes dynamic elements.

We then loop over the tabs by passing them into WP_Screen#add_help_tab(). That’s it! If we want the darker right sidebar that is persistent across all the different tabs, we also need to pass content into WP_Screen#set_help_sidebar(). Even if you don’t have content for it, not displaying this sidebar just doesn’t look right (try it if you don’t believe me); just pass in ‘ ’ (a single space) to make it appear empty.

Et Voilà:

The help box expanded with the custom added tabs and sidebar shown

Something’s not right …

If you were savvy, you might have picked up on something I [ahem, intentionally] overlooked. Because the load-{filename} hook doesn’t take into account the post type for the edit screens, our book-specific tabs are showing up for posts, pages and all the other custom post types we’ve (hypothetically) defined that have nothing to do with our literary subject! Luckily, the solution is easy, and we already have the tools to fix it.

In our captured WP_Screen instance, we have two properties we can use to determine if we are on a book edit screen: WP_Screen#base and WP_Screen#post_type. The base property will tell us the “base type of the screen.” In this case, it will be set to 'post'. Likewise, post_type gives us the “post type associated with the screen.” We will, of course, be looking for 'book'. A quick conditional in cjr_add_help_tabs() will help us bail if we aren’t on a book-related edit page:

And that’s that!

Here’s the complete code from above:

This particular example is fairly basic and works well for very specific plugins or simple stuff defined in a theme’s functions.php. If your plugin or theme adds custom functionality over many aspects of the admin, it might make sense to improve on this solution to be more flexible. As a starting point, the WordPress Codex has a class-based example that is slightly more robust but could probably be taken further.

Oh, and one more thing. Recently, the WordPress core developers have been focusing on this feature to some extent, including testing a new layout for the tabs (with a mention of the change being implemented by version 3.8). While I’m certain they won’t be affecting the API for adding tabs and content, I would encourage you to not make any assumptions about the placement of these tabs to keep your implementation future-proof.

Happy documenting!