One of the things that has become relatively common within themes that offer a lot of options is the use of tabbed navigation. That is, options that are related are logically grouped into tabs and then the user can navigate through each tab in order to select the options.

Whether or not this is a good thing for themes is outside the scope of this particular post; however, another place in which tabs may also be used is within the context of custom meta boxes.

That is, a custom meta box sits below the post editor and it offers several options or additions to the post meta data each of which is group together in their own tab.

Though I personally find this a bit more effective than using tabs of pages for screen options, that discussion is outside the scope of this post.

Regardless, there are ways to improve the ways in which custom meta box tabs are created such that they are organized in a more maintainable way, and each tab has its own view, partial, or template so that it’s easier to work with over time.

Custom Meta Box Tabs

Before actually looking at a way to go about implementing this, note that we’re only going to be looking at the frontend code for how to do this.

To that end, there are several things worth noting about the code that we’re going to review:

  • It’s possible to go overkill with options in custom meta box tabs. This example is not meant to help influence doing that.
  • This assumes that you’re familiar with the post meta box API and that you’re familiar with how to use JavaScript to navigate through the tabs.
  • This assumes that you’re taking care of all of the backend work on your own such as checking nonce values, sanitizing, and serializing data.

With that said, let’s say that we’re introducing a meta box that has three tabs each of which is responsible for maintaining its own set of data. One tab may contain a text area, one tab may contain a file upload, and the other may include a select element.

For the purposes of this example, we’ll call each tab:

  1. Extended Description
  2. Related Files
  3. Similar Posts

Then, when the user tabs through each option in the meta box, they’ll see the options related to the title of the tab. Through the particular implementation of what each tab does isn’t really necessary for the purpose of this post, here’s way the UI may look like:

Custom Meta Box Tab Example

As far as the frontend code is concerned, it’s not at all uncommon to see one giant PHP file that contains the tabs, the content for each tab, and the nonce value for each post.

However, I find that that makes it more difficult to maintain and leads to less cohesion when working with tabbed navigation. To that end, I try to break down the organization of these files as follows:

  • A views directory for the primary wrapper that contains the tabs
  • A partials sub-directory that contains well-named files for each of the tabs
  • A nonce value that’s stored in the parent view (since that’s what should be verified when saving the post)

So the directory structure looks something like this:

Custom Meta Box Tab

And the primary template for what you see above looks like this:

From there, each partial is relatively simple. For the sake of trying to keep this as concise as possible, I’ll give an example for the tab that you see above:

Then, you repeat the same organization for each of the above tabs, make sure to verify the nonce on the backend when saving the information, and make sure that you sanitize data properly when saving the information.

If there’s interest, I may do a follow up post for this that goes into more of what’s going on into the backend. But in the meantime, hopefully this leads to better organization of your frontend code at least as far as custom meta box tabs are concerned.

Category:
Articles
Tags:

Join the conversation! 13 Comments

  1. Thanks for sharing this Tom. Always interested in articles like these that help separate code in more logical way. I do hope in future if you get a chance, an article with a working example of any plugin using your plugin boilerplate and how the code separation is actually done would be helpful. That is one thing I still struggle with.

    • I do hope in future if you get a chance, an article with a working example of any plugin using your plugin boilerplate and how the code separation is actually done would be helpful.

      This is something that I’d like to eventually do with the latest version; however, the Boilerplate plate itself is a bit of a working plugin (albeit very simple).

  2. Interesting post. I’ll implement it into my new plugin.
    Full, working example or explanation how the backend works would be very helpful.

    • I do hope in future if you get a chance, an article with a working example of any plugin using your plugin boilerplate and how the code separation is actually done would be helpful.

      That would be something for a longer tutorial. I may consider doing something like that in the future – we’ll see!

  3. Best article I’ve found so far on this topic. Implemented and it worked right away in WP 4. Thanks a bunch.

  4. Just want to give you a heads up… the “looks like this:” link is broken. Great post!

  5. What if multiple tabs use the same partial, e.g., a text input and a textarea? Obviously you would want to reuse the HTML scaffolding, and just fill in the saved post meta based on which tab is active, but how would you handle multiple tabs’ worth of content using the same HTML elements without saving each time you wanted to switch tabs?

    • I don’t know if what you’re proposing is the best idea because each textarea and each input element will need its own ID and name as generated by WordPress.

      If you’re able to generate something like this based on when the tab changes (which is possible), then there are a couple of ways to go about doing this.

      One way is to retrieve the post meta data when the page loads and store it in a hidden input element. Then, when the tab is clicked that corresponds to the data that you’d like to display, you can grab it from the hidden element and then place it in the element of your choice.

      Another alternative would be to retrieve it “on-demand” whenever the tab is clicked and then retrieve the information via Ajax.

      • Thanks for your prompt reply! I think you may be right in that the simplest approach is to stick to a separate partial file for each tab, since every input/form element is going to need IDs and names for retrieving/updating post meta. Maybe in this case it’s not such a huge deal that each partial file contains the same set of elements. :)

  6. I’ve been using tabbed interface in couple of my plugins. They are easy to work with and greatly simplify data entry screen. Single meta box can have quite a few options divided into logical sections.

    The only thing missing from making it perfect is to open the last tab used after Save and screen refresh.

    In the above example editing Related Files and saving the record would show Related Files tab as active.

    • I’ve been using tabbed interface in couple of my plugins. They are easy to work with and greatly simplify data entry screen. Single meta box can have quite a few options divided into logical sections.

      Agreed!

      The only thing missing from making it perfect is to open the last tab used after Save and screen refresh.

      I’ve some ideas around this. I just haven’t had time to create anything to experiment with it yet (though I doubt no one has done anything with it :).

Leave a Reply

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