If you’re using functions such as add_menu_page or add_submenu_page to create pages in the WordPress dashboard, it’s pretty easy to get something up and going, but what if you’re looking to actually save WordPress submenu page options?

Submenu Page Options

That is, let’s say you’re creating a page in the dashboard that’s tied to a new menu item – perhaps something that’s being added to the Tools menu – and you want to display some options among some other text or some other element or set of elements that you’re displaying.

It’s completely possible to use the Settings API to do exactly that, but it may also be a little heavy-handed for saving a couple a small set of options.

Luckily, WordPress has a hook that’s available that makes it pretty easy to save information like this that’s completely usable outside of the Settings API.

Save WordPress Submenu Page Options

When working through this scenario, there are a number of things that we need to take into account:

  1. Adding the submenu page item
  2. Rendering the display for the submenu page
  3. The content for the submenu page
  4. Saving the options displayed on the submenu page
  5. Making sure that the user has permission to save the options

I’ll break down each of these into their own set of code samples (if you’re reading this in an RSS reader that doesn’t support GitHub gists, then you may want to hop into the browser to read the remainder of this post), with comments.

Of course, I can’t predict each and every use case so I’ve done what I can to comment the code as best as possible where it will vary depending on your implementation.

1. Add The Submenu Page

First, assume that a new submenu page has been added to the WordPress dashboard via the add_submenu_page API. To do this, we’ll use the admin_menu hook and then define a function like this:

If you’ve used this hook and this API call before, then there’s nothing that should be particularly interesting about the code above; however, if you’re new to this function then you may see the manage_options argument.

This is the capabilities requires to view this menu. For more information about this particular argument, see this page in the Codex.

2. Render The Display For The Submenu

Next, we need a function that will render the content of the page that’s related to our submenu page. This is the acme_render_submenu_page argument in the previous section.

I generally define these types of functions as simple as possible:

Notice that I’m only making a single call to include_once and it pulls in an external PHP file. I do this because I think including marking in the context of a function inside of a PHP file makes the file hard to follow, difficult to trace, and generally mixes too many different languages in a single file.

3. The Submenu Page

To that end, I usually create an external file. The file will still include certain calls to the WordPress API (such as wp_nonce_field) but usually consists of more markup than PHP.

For example:

Make sure to notice the HTML comment in the code above. In some cases, this may be something as simple as an input element; other times, it may be a little more complex.

Whatever the case, name the elements carefully as they matter when it comes to saving the options.

4. Saving Options

In order to save the input from the user, we generally have to make sure the user has permission, then we have to sanitize the input, then we save it (or delete it).

Heads Up…

Perhaps the key to this entire post lies with the name of this hook: load-tools_page_acme-submenu-page which you can see defined at the top of the file.

This is a dynamic hook that WordPress provides that allows us to hook into the display of the submenu page. You can read a little bit more about this in the Codex but suffice it to say that this function will fire whenever the page with the specified ID (in our case, acme-submenu-page) loads.

This is why we need to check to see if the user has permission to save as it will check to see if the $_POST collection is even set. If it is, then something is being submitted.

Okay, Back To The Code…

Notice that we’ve defined the $action and the $nonce values based on the arguments we passed to wp_nonce_field in the previous section. I’ve also got a function called acme_user_can_save that we’ll look at momentarily.

In the meantime, the important thing to note here is that whenever you’re inspecting the $_POST collection, you need to make sure that you’re checking the index of the array based on the name attributes of the elements that you’ve defined when creating the markup for the page.

Finally, you may not want to delete options if the value doesn’t exist in $_POST; however, I usually opt to do this because it means the user has unset, cleared, or reset the element from whatever value it previously had.

If you opt not to do this, then the value may always be set.

5. Make Sure The User Has Permissions

Finally, as a security measure, we want to make sure that the user has permission to save the information.

Here, we check two things:

  1. That the nonce value is set in `$_POST`
  2. If the value is set in `$_POST`, then it validates against what WordPress is expecting

If both of these values are true, then we’ll assume the user has permission to save their information; otherwise, the function will return false and whatever has been submitted will not be saved.