One of the great new features in WordPress 3.4 is the Theme Customizer which allows you to modify options for a theme and instantly preview them on the site.
I’d encourage you to try out the Theme Customizer, but first upgrade to the latest version of the Options Framework (1.3). Earlier versions explicitly checked for $_POST[‘update’] in the request before saving anything to the database, which doesn’t allow options set via the Theme Customizer to save properly.

Approach to Theme Customizer Support
When I originally started working with the Theme Customizer in the Options Framework, I thought about creating a method for all the defined options to automatically get outputted for use in the Customizer- no extra work required. I quickly discovered this was a bad idea.
A couple reasons why:
- You might want to order options differently in the front end customizer than you would in the options panel. For instance, options related to the site title & tagline should probably go in that section, rather than the tab defined in the Options Framework.
- It wouldn’t make sense to output options that don’t actually change the theme appearance
- Options that may work in a larger panel may not fit in the limited space of the Theme Customizer
Another idea I had was to add additional parameters to the $options array so that it could know which options to output for the Theme Customizer. For instance, a text option to be displayed in the “Navigation” setting could get written like this:
$options[] = array(
"name" => "Text",
"id" => "example_text",
"std" => "Default Value",
"type" => "text",
"theme_customizer" => true,
"section" = > "nav");
But that seemed to overcomplicate it. Some developers may still want to take this approach to outputting their options to the Theme Customizer (and you’re welcome to), but it doesn’t make sense to build this into the core plugin functionality.
Use Core Methods
In the end I decided the best way to support the theme customizer is to just use the Theme Customizer API as it was intended. (It actually didn’t take that long to come to this conclusion, I just want folks to understand the reasoning behind it).
The Theme Customizer API is actually really awesome. If there was something like this in the core Settings API we wouldn’t need the Options Framework.
When you define a control like “text”, “checkbox”, “radio”, “select”, “image” or “colorpicker”, all the required HTML and scripts are automatically outputted to make that option work. It’s lovely.
Getting Started
If you haven’t already read Otto’s post about leveraging the theme customizer I suggest you do that now. The rest of this post will make more sense if you understand how the Theme Customizer works.
If you have read Otto’s post, you’ll notice he mentions three different ways that theme options can be set. The Options Framework uses “Serialized Settings”, which is the method suggested by the Theme Review guidelines and the one that Otto primarily covers.
Option Name – Defined Programmatically
In some of the example themes for the Options Framework I have the default option name set like this:
function optionsframework_option_name() {
// This gets the theme name from the stylesheet (lowercase and without spaces)
$themename = get_option( 'stylesheet' );
$themename = preg_replace("/\W/", "_", strtolower($themename) );
$optionsframework_settings = get_option('optionsframework');
$optionsframework_settings['id'] = $themename;
update_option('optionsframework', $optionsframework_settings);
// echo $themename;
}
If you use this method, the option name in use is the theme name (but in lowercase, and with spaces replaced by underscores). With this method child themes will have their options saved under a different option name.
If you want to continue using this method, you’ll need to use that variable throughout the theme customizer code for it to work correctly with both parent and child themes.
Option Name – Defined Manually
Another way to set theme option name, is to manually define it. This is the method I generally use in my own projects:
function optionsframework_option_name() {
$optionsframework_settings = get_option('optionsframework');
$optionsframework_settings['id'] = 'options_theme_customizer';
update_option('optionsframework', $optionsframework_settings);
}
This means that the option name is set to “options_theme_customizer”, and it will use that same option name even with child themes.
For this tutorial, I’ll assume you’re using this second method.
You’ll need to know the option name when you set up the Theme Customizer code so that it can save changes to the option name. (In my code example, I use the option name “options_theme_customizer”.)
Tweaking Your Options Array
If you’ve set up your theme options array like the example in the “options-check” theme, it probably looks something like this:
$options[] = array( "name" => "Text", "id" => "example_text", "std" => "Default Value", "type" => "text" ); $options[] = array( "name" => "Select Box", "id" => "example_select", "std" => "First", "type" => "select", "options" => $test_array );
However, with the Theme Customizer we’ll want to reference these specific options in this array- so it’s useful to assign a key to each option in the array.
I’d suggest using the name value as the “id” parameter. Like so:
$options['example_text'] = array( "name" => "Text", "id" => "example_text", "std" => "Default Value", "type" => "text" ); $options['example_select'] = array( "name" => "Select Box", "id" => "example_select", "std" => "First", "type" => "select", "options" => $test_array );
Setting Up the Theme Customizer
Now you can add the code for the theme customizer.
This can be put wherever you think it’s appropriate in the theme, but I’d suggest adding it to options.php underneath the optionsframework_options function. This works perfectly when using the plugin version and also means it won’t be loaded if the Options Framework Plugin has been disabled.
However, options.php appears to load too late when used in the theme version. I haven’t traced down exactly why this is yet, but to get around it you can include options.php directly from your functions.php file:
require_once dirname( __FILE__ ) . '/options.php';
Front End Customizer Code
To create Theme Customizer options for the two option listed in the example array above, you would add this:
/**
* Front End Customizer
*
* WordPress 3.4 Required
*/
add_action( 'customize_register', 'options_theme_customizer_register' );
function options_theme_customizer_register($wp_customize) {
/**
* This is optional, but if you want to reuse some of the defaults
* or values you already have built in the options panel, you
* can load them into $options for easy reference
*/
$options = optionsframework_options();
/* Basic */
$wp_customize->add_section( 'options_theme_customizer_basic', array(
'title' => __( 'Basic', 'options_theme_customizer' ),
'priority' => 100
) );
$wp_customize->add_setting( 'options_theme_customizer[example_text]', array(
'default' => $options['example_text']['std'],
'type' => 'option'
) );
$wp_customize->add_control( 'options_theme_customizer_example_text', array(
'label' => $options['example_text']['name'],
'section' => 'options_theme_customizer_basic',
'settings' => 'options_theme_customizer[example_text]',
'type' => $options['example_text']['type']
) );
$wp_customize->add_setting( 'options_theme_customizer[example_select]', array(
'default' => $options['example_select']['std'],
'type' => 'option'
) );
$wp_customize->add_control( 'options_theme_customizer_example_select', array(
'label' => $options['example_select']['name'],
'section' => 'options_theme_customizer_basic',
'settings' => 'options_theme_customizer[example_select]',
'type' => $options['example_select']['type'],
'choices' => $options['example_select']['options']
) );
You can see how the options array that was defined in optionsframework_options gets reused to output the default, label, type and choices- so they don’t need to be defined again separately.
I realize it’s a lot of extra code just too add two options to the Theme Customizer- but it’s easy enough to write (and makes you think much harder about whether an option is really needed or not).
If you did want to set up some sort of loop or function to do this instead, you’re welcome to do that as well.
What Options Are Supported
You’ll notice in Otto’s post there are example for several types of options supported by default.
The Options Framework has a couple additional option types it uses: textarea, multicheck, wp_editor, background and typography. I haven’t decided the best route to support all of these yet.
Textarea could easily be outputted as a “text” option instead. An actual textarea field might take up too much room in the Theme Customizer panel.
wp_editor won’t be supported. Doesn’t make sense.
The others are actually just groups of default options (e.g. typography is several select boxes), which could be supported in a couple ways:
- A function could add all the individual inputs for these options in the Theme Customizer.
- The Theme Customizer class could perhaps be extended
- Each field could be manually added. (e.g. options_theme_customizer[example_background][color] can be set on its own).
I need to try this all out a little more before I can make a recommendation.
More Code Examples
I have demo code available as a separate theme in the Options Framework Plugin repo. Eventually I’ll merge it into the Options Check demo.
If you want to see code with all the default options listed, check out this file.
I’ve also added a demo to the theme version and plugin version of the Options Kit.
Notes on Sanitization
When your options get saved it runs through the regular sanitization filters for the Options Framework- which means the same rules apply to options set via the Theme Customizer as through the standard options panel.
However, that sanitization just occurs when the options are saved- not necessarily when someone is altering their options on the fly with the Customizer. Add sanitization where you need it.
Notes on postMessage
When you’re working in a local dev environment and update an option, the page refreshes quickly and you see the update almost immediately. However, this might not be the case for users with slow connections.
If you’re interested in using postMessage and avoiding a page refresh I’d recommend reading the rest of Otto’s tutorial and look at how Twenty Eleven does it.
Conclusions
As you can see there’s still a couple kinks and bottlenecks to work out- but I hope to have them solved soon. If you want to help you can always post a bug report to the GitHub repo and send over a pull request.
It’s also been great to see all the orders come through for the Options Kit. I’ve been spending a lot of evenings and weekends putting together examples and tracking down bugs- so everyone’s support has been much appreciated.
And big thank yous to everyone who has chipped in on some debugging of the checkbox options via twitter and e-mail- especially Otto. You folks are terrific. This is why I love building things for WordPress.