Post Options API for WordPress

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:

Post Options API for WordPress

An Overview of Predefined 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.

Post Options for WordPress

Real-world Examples and Custom Callback Demos

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_api creates the API object used to add sections and fields, as well as add sections to post types
  • get_post_options_api_fields creates 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 Github

We 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!