You probably heard about the Post Options API project that we’ve been working on for a couple of months now. It’s a set of functions that allow you to easily create additional fields in posts and pages edit screens. Quite a good alternative to the native WordPress Custom Fields.
We’ve done some major modifications to the API in the last few weeks and today we’re glad to announce that the project is in beta and open for feedback. If you haven’t read our introduction post earlier this month then you probably should, since today we’ll talk about the new structure, the API and other changes.
A Quick Overview
Post Options API is a simple php file that you bundle together with your WordPress theme or plugin. It consists of two classes. The main class wraps a lot of the logic behind the API, the metabox creation, saving, sorting, validating and sanitizing. The second class provides a set of predefined fields, like checkboxes, text inputs and areas, radio buttons and select drop-downs.
Using the predefined fields is optional since the API itself is built similar to the WordPress native Settings API allowing callback functions for field controls.
Anyhow, speaking about the classes, you should never use any of the two classes directly. This is a compatibility limitation which allows the API to work well even if ten different plugins that use ten different versions of the Post Options API are activated simultaneously on a WordPres site.
Before diving into the code, here’s a screenshot of one section that contains five different options with different controls:
And here’s another screenshot illustrating some custom callback functions and real-world examples. This means that you can write your very own set of callback functions to use if you don’t like the ones that we have provided.
Getting Started
Getting started with the API is quite simple. As mentioned earlier you’ll need to bundle the library together with your theme or plugin and include the php file during WordPress init. We recommend and inc directory in your theme and plugin file, and then something like this inside your functions.php file (or the corresponding plugin source file):
function your_function() {
// Initialize Post Options API
require( dirname( __FILE__ ) . '/inc/post-options-api.1.0.php' );
$post_options = get_post_options_api( '1.0' );
$post_fields = get_post_options_api_fields( '1.0' );
// Add the fields here
}
add_action( 'init', 'your_function' );
As you can see the function is run during WordPress init. It includes the API file, not that the file name will change from version to version. Right after including the file you can initialize the two libraries which I talked about earlier using the corresponding initialization functions:
get_post_options_apicreates the API object used to add sections and fields, as well as add sections to post typesget_post_options_api_fieldscreates an object that contains custom callback functions which you might or might not want to use.
Note that both functions receive a version as their one and only argument. Make sure that version is correct, otherwise you’ll end up with a WP_Error object telling that the requested version was not found. The two bundled classes are Singletons so you don’t have to worry about multiple initialization calls to both APIs, they will return the one and only corresponding object once initialized.
Creating Sections
We asked for your opinion a while ago about the current roadmap and based on that we have decided that each section is a WordPress metabox of it’s own. That way the end user can move sections around, show and hide them using the Screen Options panel.
So, in the code snippet above, right where it says Add the fields here let’s create a section and add that section to a post type, like this:
$post_options->register_post_options_section( 'example-section', 'Example Section' );
$post_options->add_section_to_post_type( 'example-section', 'post' );
That will create a new section called Example Section and display it’s contents in the post edit screen. It will be blank for a while since we haven’t added any real options there yet, but you can go ahead and see how the section is represented on the edit post screen. Try toggling it’s visibility and moving it around.
Creating Fields (Registering Options)
When we’re talking about post options fields, we’re not referring to controls only. We’re referring to the option in general, including the control, title, key, sanitization, validation and the whole saving process too.
Post Options are saved to post meta under the option_id meta key and could be later retrieved via the get_post_option method or the WordPress native get_post_meta function. You should go for the Options API method though since meta keys naming may change in future releases.
Here’s how we register a simple text field, right after you have added a section to a post type:
$post_options->register_post_option( array(
'id' => 'an-input',
'title' => 'A text input',
'section' => 'example-section',
'callback' => $post_fields->text( array(
'description' => 'This is an example text field.'
) )
) );
This shows how a post option is registered to our example_section and if you browse to your edit post screen now, you’ll see the option in action. This also illustrates the usage of the predefined callback functions from the $post_fields object, in this case we’re calling the text method which produced a simple text input.
Custom Callbacks & Sanitize Callbacks
When registering a post option you can use your own callback function if you don’t want to use any of the predefined ones in $post_fields, like this:
$post_options->register_post_option( array(
'id' => 'custom-callback-example',
'title' => 'Custom Callback',
'section' => 'example-section',
'callback' => 'my_custom_callback'
) );
Which will call a function called my_custom_callback when rendering the control. The custom callback will receive an array of useful stuff, like the current value and the name attribute that you should use for your control. Use print_r to inspect the argument passed to your callback function.
You can pass additional arguments to your own custom callbacks as well, in this case the callback key should be set to an array containing a function key with your callback function and an args key for your additional arguments. Like this:
$post_options->register_post_option( array(
'id' => 'custom-callback-example',
'title' => 'Custom Callback',
'section' => 'example-section',
'callback' => array( 'function' => 'my_custom_callback', 'args' => array( 'foo' => 'bar' ) )
) );
In this case the foo-bar array will be merged with the array which is passed to your callback function. It will now contain the current option value, the name attribute and a new key called foo with the value of bar.
Sanitizing is done in a similar way, the callback array keys are sanitize_callback and sanitize_callback_args. The predefined functions will accept these as arguments as well if you need to. Here’s an example of using the WordPress sanitize_title function for a text field:
$post_options->register_post_option( array(
'id' => 'an-input',
'title' => 'A text input',
'section' => 'example-section',
'callback' => $post_fields->text( array(
'description' => 'This is an example text field.',
'sanitize_callback' => 'sanitize_title'
) )
) );
And here’s how you use the same sanitize function in your custom callback array:
$post_options->register_post_option( array(
'id' => 'custom-callback-example',
'title' => 'Custom Callback',
'section' => 'example-section',
'callback' => array( 'function' => 'my_custom_callback', 'sanitize_callback' => 'sanitize_title' ) )
) );
You’ll find these and much more examples in the plugin sample that is provided together with the API which you can simply copy into your wp-content/plugins directory and see it in action.
Join Us on Github
Post Options API is hosted on Github. The latest release can be grabbed from the lib tree and we’re currently at version 1.0.1. Although we do believe that the Post Options API is ready for use we wouldn’t recommend to use it in production yet (although we do use it already). We’ll have an official announcement soon, probably early September.
Post Options API on GithubWe know how some of you would love to start using this today, but we’re asking you to give it a spin and tell us what worked and what didn’t. Use the Github Issues section to report bugs and errors and use the comment section below for some general feedback if you have any. Thank you all for contributing and stay tuned!




I’m testing it in a plugin and I have a question: is it possible to update the value of a textarea field based on the value of another field? for example if I check a checkbox, it updates a text field when the post is saved
Hi Paul, I’m not sure it is but I guess it could be useful. Do you mind opening an issue for that on the github project?
thanks, I did that.
another question : what’s the best method to debug admin side code? I want to see the post options array and values
Thanks and your second question is cool as well, makes me think of adding an action that would run after each option is printed to the table. That would allow you to debug while using the predefined controls.
Alternatively I can introduce a method that would return the array of all registered post options, you can then loop through them and use
get_post_optionto get their values.What do you think? We can take this discussion to Github too, since it seems like something useful for developers.
Really love this idea ! I’m already using it :)
I think it would be nice to extend this classes to Settings API in order to quickly setup theme/plugin options pages. I imagine smoething like 3 classes to handle this :
- A more global class for UI elements (radio, text, select, etc.)
- A class for Post_Options
- A class for plugin/theme options
What do you think ?
Might be a different project Nico, since the Settings API is a little different and not really related to posts and posts meta.
First of course I have to say I’m really liking the Post Options API thus far. Besides Bill Erickson’s similar approach and, the html5 boilerplate bits of course, it’s listed in my daily favorites.
A newby as I am (I don’t seem to read and write fluently php yet…), could you perhaps -in a next article perhaps- list its full features?
Does it in example include attachments, like the somewhat outdated Attachments plugin does (but more pretty of course), or does it include a jQuery date picker?
Cor, those are good questions and unfortunately the production launch of the API has been delayed since we’re all extremely busy here, but we’ll get there eventually and of course cover it with a blog post. After that we’ll probably get some docs up and running too. Thanks for your comment!
Hello Konstantin, That’s OK. After some digging I’ll probably figure things out. Thumbs up thus far!
As for the jQuery date picker bit, I’m correct if it isn’t included (yet) right?
Yes you are Cor, but then again, it’s easy enough to create a custom callback that would use a jQuery date picker when needed. You see, we didn’t want to bundle all possible options inside there since there are too many, but provide the most common ones that could be used out of the box and leave the rest up to the developers who can write their own set of field callbacks and reuse them in every project they work on :) if that makes sense…
Hey Konstantin!
I was wondering if you think the code is somehow ready to be used in a project/theme… If you tell me it is I’ll include it immediately on my code, otherwise I’ll just stick to the ole’ add metabox function. What do you say?
P.S. It looks great, by the way!
Hi Javier. Depends on what you’re doing. As we figured out with Zack on Github, there seems to be a memory problem which I’m still trying to fix, so on projects which you host and manage yourself you’ll be fine but themes — I wouldn’t risk that yet unless you’re using it for like 4-5 options.
Also, considering that the Post options UI just works at the backend, could we try a less-resources way and call it at admin_init instead of calling it at init?
Working on this too, if you’ve got ideas feel free to post them as issues in our GitHub repository. Thanks! :)
Great! I’ll keep all this in mind. Perhaps for this one I´ll go the old fashioned way and then I´ll incorporate the API.
Thanks as always for answering! :)
You’re welcome Javier :) thanks for your support!
Hello Konstantin,
Perhaps I should have asked (again) at github, but would it be possible to do multiple checkboxes with the code as-is?
Cor, I don’t think it’s semantically correct since each option is represented by one key, but I guess you can easily group the checkboxes under one option and get their names to be two-dimensional arrays, that way the API should store the values as an array to the key. You’ll have to work with the array when getting the values too.
I can’t guarantee about browser compatibility, you should check for yourself, but this should be done with a custom callback. Look at the custom callback example in the plugin.
Hope this helps. Cheers!
Any words on updates? :)
So has development stopped on this???
Really looking forward to its release…