Create WordPress Settings Page With Meta Boxes

In this tutorial I want to explain Step by Step How To Create WordPress Settings/Options Page With Meta Box, like what you see in this screenshot:

WordPress Settings With Meta Box

WordPress have a decent Settings API and it offer a lot flexibility in design. Several plugins do “wild” things in their Settings Page, However for better user experience it’s best to use seamless design (blended) with other admin UI design.

One of my favorite admin UI element is Meta Box. Not only because meta box have an easy to use Meta Box API (so we can easily create meta boxes), but it also have user preference options where user can reorder (drag-and-drop) the position, toggle open/close meta boxes. and even changing Screen Layout to 1 or 2 column using “Screen Options”.

The function fx_smb_settings_setup() is to register our settings and add settings in admin menu. And we will use the utility function fx_smb_setings_page_id() to refer our settings page, for example to enqueue scripts.

I use admin menu name “Meta Box” just because (no reason) and add in menu position 5, which is after the “Dashboard” Menu to make it easier to display it in the screenshot 🙂

After we have this function in place we will have a blank settings page ready.

Create Settings Page

In our (currently blank) fx_smb_settings_page() function we will add our HTML markup for the settings and use the “Post Edit Screen” Markup.

You can check “wp-admin/edit-form-advanced.php” if you want to learn more about the HTML structure and functions. I simplify the markup in post edit screen and only use what we need.

After we add this code in our function we will still see the empty settings page, but now we have a settings title, “Settings Meta Box” (in H2) at the top of our settings page.

Use Settings API Functions

As you can see above, I use several function in Settings API you already familiar with:

settings_errors() : this is to display “Updated” and “Error” message when we save or reset our settings.

settings_fields(): this is needed in Settings API, this is where WordPress handle settings we register to this page using register_setting() function.

But we are not using add_settings_field() and add_settings_section() function, because we are going to add our settings using Meta Box API.

Enable Meta Box in Settings Page

So to replace add_settings_field() and add_settings_section() functionality, we need to enable Meta Boxes API in our settings, and to do this we use do_meta_boxes() function:

do_meta_boxes( $page, $context, $object );

There’s three instance of do_meta_boxes() for each meta box context / location ( “side”, “normal”, and “advance” ), and we use global $hook_suffix as the page identifier.

Usually when we add our meta box in Post Edit Screen, we define the page using post type as identifier ( “post”, “page”, or “our-cpt” ), and now if we want to add meta boxes in this settings page, we simply change the page with our settings page $hook_suffix. and it’s the same return value with our utility function fx_smb_setings_page_id().

The function do_meta_boxes() will do nothing, To enable it we need to add add_meta_boxes action hook, as you see we have this code: do_action( 'add_meta_boxes', $hook_suffix ); at the top of the page.

We also add an utility hook fx_smb_settings_page_init at the top of the page and we will use this later.

Enable Meta Boxes Functionality

Adding meta box is not enough, we also need to enable Meta Box functionality, such as “reorder meta box” using drag and drop, “toggle meta box“, and change the “screen layout“. This functionality require several script, and we need to add these scripts in our Settings Page.

Let’s back to fx_smb_settings_setup() function to add scripts needed and set number of available screen layout column.

To save this user preference in user meta, we need to add nonce in our settings page, If you check fx_smb_settings_page() function there’s two nonce field added, one for meta box toggle, and one for meta box order. We need to add it inside the form, and I add it after settings_fields( 'fx_smb' ); function:

As you can see, we use “submitdiv” as Meta Box ID, this is the same ID as “Publish” Meta Box we see in Post Edit Screen, We also reuse HTML elements in “Publish” Meta Box. This provide several benefit:

No need to style it, it will use the same design as “Publish” Meta Box.

The “Save” Option functionality is working at this point, because WordPress Settings API have this build-in, so the “Save” button will work. But the “Reset Settings” link is not yet working. We need to build this functionality our-self, because WordPress do not have this functionality. This feature is optional,

So it’s just the URL to our settings page with additional parameter to reset settings and nonce to make it secure. This URL still do nothing, To actually reset the settings we are going to use our utility hook “fx_smb_settings_page_init” in fx_smb_settings_page() function:

I explain this because there’s a popular settings framework doing it wrong and save the default option instead of deleting the option in their “reset” functionality.

Fine-tuning “Save Options” Meta Box:

If you check in our “Save Options” meta box function fx_smb_submit_meta_box(). Above the submit button, there’s a “spinner” empty span. This span as default is hidden using CSS, and when we submit our form, we need to display it. This is to notify user that the submit button is working and processing the data. We also need to create a pop-up confirmation if user want to reset the settings. We can add simple javascript to do this in fx_smb_footer_scripts().

In the example I only create one text field, and it is saved in “fx_smb_basic” option name. If you want to create several field in the meta box you can also save them in single data entry as array, This can make the database leaner.

Database Schema Notes:

If you need more than one meta boxes, It is better to use register_setting() for each meta boxes. That means, save each meta box data in different option_name.

It will offer more flexibility when we need to create / remove additional meta boxes/settings.

If you save all meta boxes data in one data entry and In the future you need to remove additional meta boxes, when user save the data, all previous data will be lost (sometimes this is not wanted). This will also make the database structure more manageable.

Example use case: If we create an add-on plugin for the “main” plugin. And this add-on create additional meta box options.

Design Notes:

If you want to prettify the meta box design, always remember:

WordPress Admin is Responsive, make sure user can easily input the data using small screen device.

User can change meta box order, and drag the meta box in “Side” location (context). Make sure all field look neat there too.

Check out WordPress default meta boxes, there’s several HTML class you can use, for example “howto” class for explaining a field.

Well, that’s it. If you have questions or suggestions, leave a comment. If you think it will be useful for others, share 🙂

I have a custom post type in which I added a couple of meta boxes. I’m having difficulty figuring out how to save the information all the custom post information. I’m relatively new to WordPress. Any advice on how to get that figured out? This is what I have in the custom plugin…

Nice tutorial, however the reset option logic doesn’t work well, as the nonce and reset query args stay on the url, so if you reset and then change settings, they reset ( when that is what is not intended )

Ben thinking of ways around it, I think teh way to do it is with another option (reset) and pick this up in say sanitise ..