Recently the Theme Review Team chose to make the customizer as the format of creating theme options. I love it! Yes, I was in favor of it. I have my reasons. I know there are some people that still don’t fully grasp the customizer and most likely won’t. All good! Some take a little more time than others; I know I do sometimes with certain things.

How it works

Okay. This little post will deal with customizer settings, controls, sections and panels. Yes. At the time of this writing the WordPress version is 4.2.1 with 4.3 just beginning. In the following I will make an attempt at giving you ( the reader ) a little more insight into how the WordPress customizer works and what is available within the customizer.

In order to understand the customizer a little more I dove into the core code. I asked myself a simple question, “when and where is it being created?”

Funnily enough it is done in one simple function. _wp_customize_include. It is a callback function that is hooked to plugins_loaded. Yes, I went ahead and looked up a lot of the code for you. What’s pretty cool is that in order for the customizer to work it needs five files. Yes, five. To a degree 7 but the other two are the customize.php and class-wp-customize-widgets.php files. For the purpose of this post I’ll only really dive into the five customizer ones.

Let’s look at the function:

function _wp_customize_include() {
	if ( ! ( ( isset( $_REQUEST['wp_customize'] ) && 'on' == $_REQUEST['wp_customize'] )
		|| ( is_admin() && 'customize.php' == basename( $_SERVER['PHP_SELF'] ) )
	) )
		return;

	require( ABSPATH . WPINC . '/class-wp-customize-manager.php' );
	// Init Customize class
	$GLOBALS['wp_customize'] = new WP_Customize_Manager;
}

The key thing to remember is when you are creating your options, you are passing an object. The $wp_customize global object to be a little more specific. As you can tell from the function above, you are creating an instance of the WP_Customize_Manager and setting that as the $wp_customize global variable that can be accessed by using:

global $wp_customize;

Looking at the __construct method, it loads the needed files and adds a few filters and hooks in order for the magic to happen. Totally awesomesauce!

Boom! We have our customizer! Great! But how do we add stuff?

Adding things

In order to add our theme options we have to hook to the right place. The codex has a great explanation on this, though currently it is missing a section on how to add panels. Yes, you can add panels in order to make your theme option logic make some sense for a user.

So, in order to add things we need to know how, right? Right! What’s pretty neat is that the customizer does this with built in methods. Yes, it is very object oriented. One of the other reasons I like it. There are four methods that will help in creating a great customizer experience.

$wp_customize->add_setting();
$wp_customize->add_control();
$wp_customize->add_section();
$wp_customize->add_panel();

I say customizer experience because as a developer you will have to think about the logic of your theme options. That’s great and all but what actually starts it all? The part that we hook to in order to start our theme options is the customize_register hook. This is done from within your theme by using:

add_action( 'customize_register', 'my_theme_customize_regiter' );
function my_theme_customize_register( $wp_customize ){
	// Theme settings/options code goes here
}
// or if using a class
add_action( 'customize_register', array( 'My_Class_customize_register', 'register' ) );
class My_Class_customize_register {
	public function register(){
		// Theme settings/options code goes here
	}
}

Got it? Cool! Let’s keep moving! Let’s break down each method a little more.

The methods

What’s super cool is that the customizer makes it super easy to create a theme option experience. It does this with four different methods. Let’s take a look at each one and what each one has to offer.

add_setting

The first one we will look at is the settings. In order to create a theme option in the customizer we use the $wp_customize->add_setting method. It takes two arguments. The first one is the ID of the setting and the second is an associative array. It looks a little like:

$wp_customize->add_setting( 'theme_option', array(
	'default' => '', // The default setting
	'type' => '', // can use 'theme_mod' or 'option'
	'capability' => '', // generally 'edit_theme_options'
	'transport' => '', // can use 'refresh' or 'postMessage'
	'theme_supports' => '', // internally used in customizer
	'sanitize_callback', // the callback before setting is saved to database
	'sanitize_js_callback' => '' // used for the JS value
	) );

You don’t have to use all of them. The ones that matter most are the default, option, transport, and sanitize_callback arguments. The reason option is one that matters is in the way it will save the options into the database. The sanitize_callback matters because it runs before the setting is saved to the database so you have to make sure to sanitize it. The transport value can be important if you want the page to do a full refresh or if it will be AJAXified.

add_control

The next one to look at is the $wp_customize->add_control. This is what the user will see. Much like the add_setting it, too, we have to pass two arguments. The first one being a unique ID, and the second being an associative array.

$wp_customize->add_control( 'option_control', array(
	'label => '', // label for the control
	'description' => '', // description of the control
	'settings' => '' // the setting 
	'section' => '', // core ones are: 'title_tagline', 'colors', 'header_image', 'background_image', 'nav', 'static_front_page'
	'type' => '', // core ones include: 'checkbox', 'radio', 'select', 'textarea', 'dropdown-pages', 'text'
	'choices' => array(), // associative array of 'value' => 'option user sees'
	'priority' => '', // the higher the number the lower it will appear from the top
	'input_attrs' => array(), // associative array of 'attr' => 'value'
	'active_callback' ='' // based on preview context
	) );

So, we have a few options with the controls. Cool, right? What’s even cooler is that there are few others to use. You can also use WP_Customize_Image_Control, WP_Customize_Upload_Control, WP_Customize_Color_Control, and WP_Customize_Media_Control. They just require a little extra code.

$wp_customize->add_control( new WP_Customize_Media_Control( $wp_customize, 'media_control', array(
	'label' => 'Image selection',
	'description' => 'Choose an image',
	'settings' => 'default_value',
	'section' => 'random_slider'
) ) );

add_section

Great! Now that we know how to create a setting and a control, we can look at how to create a section to hold those settings. You’ll notice I’m using settings and options a little interchangeably. As stated earlier you can choose how to save things to the database. The theme_mods or option. How you do it is up to you. Now, let’s look at how to create a section, shall we? This too, like the previous two takes two arguments. A unique ID and an associative array.

$wp_customize->add_section( 'my_section', array(
	'title' => '', // the title of the section
	'description' => '', // description of the section
	'priority' => '', // the higher the number the lower in the customizer from the top
	'capability' => '', // default setting is 'edit_theme_options'
	'panel' => '', // if none it will show on main panel
	'active_callback' => '' // based on preview context
	) );

Simple and fairly straight-forward, right? What’s pretty cool too is that you can use the active_callback to your advantage. For example if you wanted to show a certain section only a widgetized area was being used. You could use a callback like:

// in the customizer
'active_callback' => 'widgetized_cb'
// later on in the code
function widgetized_cb(){
	return is_active_sidebar( 'primary' );
}

add_panel

Pretty awesome right? See where some of that logic can come into play? Great! Now you know how to add settings, controls, and sections. We can finally take a look at the final one: panels!

What’s super awesome is that this, too, uses two arguments. A unique ID and an associative array. Notice a pattern here? Let’s look at the available ones:

$wp_customize->add_panel( 'my_panel', array(
	'title' => '', // the title for the panel
	'description' => '', // short description of the panel
	'priority' = '', // the higher number, the lower from the top
	'active_callback' => '' // based on preview context
	) );

As you can see not a lot for the panels – yet. The customizer is constantly being worked on in core. There are a lot of things you can do to make it better if you want to help out.

Previewing

Okay, this is the part where things really come together because it deals with JavaScript. You remember in the add_setting there was an option for transport? If you want to create live previews without the entire page being refreshed, you set it to postMessage. In order for it to take place you will have to include a little JavaScript. I would highly recommend using a dedicated file for this. All you have to do is hook to the right place and enqueue it.

add_action( 'customize_preview_init', 'my_theme_preview' );
function my_theme_preview(){
	wp_enqueue_script( 'my-theme-js-preview-file', get_template_directory_uri() . '/js/my.customize.preview.js', array( 'customize-preview' ), '', true );
}

From there your JavaScript file would include something like:

wp.customize( 'setting_id', function( value ) {
	value.bind( function( newvalue ) {
		// do things
	} );
} );

Final thoughts

So there you have a slight crash course on how the customizer works and what options are available to create a good theme option user experience. There are a few little tricks and things you can also do, so go ahead and explore the core code and find out! You’ll be amazed at what you will find.


Comments

One response to “Working with the WordPress Customizer”

  1. Well explained! Thank you!