Making Themes More WYSIWYG with the WordPress Customizer

Custom wigs | WordPress customizer

The WordPress customizer makes tweaking visual settings and customizing the look of your site much more intuitive.

One of the coolest features WordPress has gotten in the last few years (in version 3.4, to be precise) is the Theme Customization API, more commonly known simply as “the customizer.”

On themes (and plugins) that support the customizer, tweaking settings and customizing the look of your site can be a much more intuitive experience. Where before you’d have large admin settings pages with oodles of options that you had to hope would change the way your site looked on the front end, the customizer creates a “what you see is what you get” (WYSIWYG) experience, so you know right away what effect each change has.

The Customizer in Action

Here’s a quick demo of the customizer. I’m dragging around widgets on the left, and the site’s front end is changing in real-time on the right. If I like the way those changes look, I can just “Save and Publish” on the top and I’m done.

Cool, right? It’s a lot quicker and more intuitive than tabbing between a settings page and the site’s front end.

We Still Need Options Pages

Not every setting is visual in nature.

There is still a need for setting screens, also called options pages: not every theme (or, especially, plugin) setting is visual in nature or will make sense in the customizer. We’ve covered making WordPress options with and without the Settings API, and those processes are still very important to know and understand. But the customizer is a better and more user-friendly way to make your visual settings user-settable, so you’ll do well to learn it.

When to Use the Customizer

For visual options and settings in themes for distribution, you’ll be best served by using the customizer.

For a one-off theme you’re making for a single client, you probably won’t use the customizer; you’ll just build it with a default that meets the client’s specific need. Same story for a one-off plugin. And, as we said, if you’re allowing for the setting of non-visual things (for example, API keys or custom permalink structures), you probably don’t want to use the customizer.

But for visual things — colors, sizes, and placement — in themes for distribution, you really will be far better served by using the Customizer API than by forcing your users to deal with a static and dull-looking admin page. The experience is better for your users, and frankly it’s easier than many of the more complex ways you can create admin-side setting pages (cough the settings API cough).

There are also some judgment calls. For example, does text that’s controllable go in the customizer? In general, I’d say if you’re mostly in a settings page, a text box (whose output location is well explained) is fine. If you’re already adding a lot of customizer controls, I think making it possible to control that text in the customizer is a good call. In either case, the final effect is that an option is set somewhere in the wp_options table (assuming your database’s table prefix is wp_) on your behalf. Then you’ll use that in the display of your theme or plugin.

Hooking In to Get the Customizer Object

Working with the customizer looks something like:

function wpshout_customize_register( $wp_customize ) {
   // All our sections, settings, and controls will be added here
}
add_action( 'customize_register', 'wpshout_customize_register' );

The crucial things to know here are:

  1. The fact that we’re hooking onto the customize_register WordPress action
  2. That that action hook will pass into our function the $wp_customize variable (we dictate the variable’s name, of course), which will be an instance of the WP_Customize_Manager class.

If you’re comfortable so far (including the bit about classes!), skip on. Otherwise, let’s look a bit more deeply.

Getting an instance of a class is a foundational concept of object-oriented programming. Objects are the mechanism by which functionality and state in a system is centralized into a concept we can reason about. I explain a great deal more about these concepts in a couple of tutorials about OOP for WordPress developers, but what we must comprehend to go on is that this $wp_customizer we’ll be using is an “object” with some “methods” (essentially functions) that’ll allow us to control and add to its internal state. This internal state is what WordPress will take back from us and use to make our customizer components. Make sense?

Basic Usage of Your $wp_customize Object

An instance of the WP_Customize_Manager class has four methods, all of which are worth knowing:

  • add_setting($id, $args) — This method takes a simple slug-like identifier, and then an array of options. This is cool—it’s the interface I wish the Settings API had. You can easily omit all the arguments in the args array that don’t matter to you. Be sure your array at least has a default value, but the rest — like a sanitizing function, setting type (would you rather it be a setting or a theme_mod?), user capability requirement, etc. — are optional.
  • add_control — These controls are how you display and control the settings that you first created with the add_setting method. There are two ways to add controls, but both rely on the idea that you are adding controls to the customizer itself. The two methods: pass a WP_Customize_Control object, or pass a slug-like $id and then an array of $args that WordPress will use to create the WP_Customize_Control object on your behalf.
  • add_section($id, $args) — The customizer API organizes the controls for customizer settings both conceptually and practically into sections. If you specify an array in your call to add_control, one of the things you might specify is the id of your section. If not, you’ll specify the section when you create your WP_Customize_Control object. The customizer has six sections baked in: title_tagline, colors, header_image, background_image, nav, and static_front_page; if those suffice to hold all your settings, you can just reuse them, and if not you’ll use add_section() to create more.
  • get_setting($id) — A quick way to retrieve settings created by add_setting(). It takes a slug-like name for a setting, and then returns that setting as an object with some pretty simple public properties. You’ll mostly use this when you want to tweak some of WordPress’s built-in settings, because otherwise you can just make sure you get all the details right when you add_setting().

Again, these are all methods of the $wp_customize object that you’ll be passed when you hook into the 'customize_register' hook with your action function.

So most, if not all, customizer code is full of calls that look like:

$wp_customize->add_setting(
 // …
);
$wp_customize->add_section(
 // …
);
$wp_customize->add_control(
 // …
);

Going a Bit Deeper on Customizer Controllers

The heart of the customizer are the WP_Customize_Control objects.

As we said, the heart of the customizer are the WP_Customize_Control objects. WordPress uses these to show the user an interface by which they can control the settings that you’re making easy to set. You can build your own, which we’ll talk about a bit in the next section, but there are actually quite a large variety available out of the box, which will take care of most use cases.

In all cases, you’ll need to specify:

  1. An identifying slug for your controller instance
  2. The setting it’s showing
  3. The visually available label
  4. The section it should appear in

We mentioned above that you can either do this by passing a single instantiated WP_Customize_Control object or a descendant, or you can specify the $id and the $args array that’ll be used to make the object when you call add_control. I actually think these two options are much easier to understand when seen in code than in my best prose, so here’s the object-only version:

Manually Instantiating a WP_Customize_Control Object

$instantiated_control = new WP_Customize_Control( 
    $wp_customize, 
    'shout_logo_position', 
    array(
        'label'      => __( 'Shout Logo Position', 'shouttheme' ),
        'section'    => 'title_tagline',
        'settings'   => 'shout_logo_position',
        'type'     => 'radio',
        'choices'  => array(
            'left'  => 'left',
            'right' => 'right',
        ),
    )
)
$wp_customize->add_control( $instantiated_control );

And then the same thing, but where we leave WordPress to make the object for us in the background:

Letting WordPress Create the Object For Us

$wp_customize->add_control(
    'shout_logo_position', 
    array(
        'label'    => __( 'Shout Logo Position', 'shouttheme' ),
        'section'  => 'title_tagline',
        'settings' => 'shout_logo_position',
        'type'     => 'radio',
        'choices'  => array(
            'left'  => 'left',
            'right' => 'right',
        ),
    )
);

Now as we can see, these two look a lot alike. It’s just that in the instantiated version we add all the parameters into the object ourselves. The object’s constructor function takes three arguments:

  1. An instance of $wp_customize
  2. The unique identifier for our control
  3. The arguments actually needed for the construction of the control

So the difference in the second is that we never have to supply the $wp_customize object as a parameter. I think the object-less version is a bit cleaner. But when you’re not using the default WP_Customize_Control class (see next subsection), you must instantiate your instance of whatever class you’re using, so getting in the habit of doing it has some benefit.

Enhanced Objects that Inherit from WP_Customize_Control

WordPress comes packaged up with a number of enhanced controls, and their naming is mercifully self-explanatory. They are:

  • WP_Customize_Color_Control()
  • WP_Customize_Upload_Control()
  • WP_Customize_Image_Control()
  • WP_Customize_Background_Image_Control()
  • WP_Customize_Header_Image_Control()

Each of these classes have inherited from or extendsed the parent WP_Customize_Control object. If the selection they all offer isn’t yet wide enough for you, you can create your own controller classes and use them.

Creating Your Own WP_Customize_Controls via Inheritance

To make your own customizer controls, you’ll use inheritance: you’ll create a class that extends a parent class—inheriting all the parent’s functionality—and then only overrides and adds what it needs. Inheritance saves you from reinventing the whole of the WP_Customize_Control class.

An example, which I’ve taken from Paulund’s awesome “WordPress Theme Customizer Custom Controls” project — look there before you spend too much time making your own — is below:

class Text_Editor_Custom_Control extends WP_Customize_Control
{
      /**
       * Render the content on the theme customizer page
       */
      public function render_content()
       {
            ?>
            <label>
            <span class="customize-text_editor"><?php echo esc_html( $this->label ); ?></span>
            <?php $settings = array(
                      'textarea_name' => $this->id
                  );
                  wp_editor($this->value(), $this->id, $settings ); ?>
            </label>
            <?php
       }
}

This class Text_Editor_Custom_Control gives you, as you might guess, the WordPress WYSIWIG editor as a customizer field. As we said, that extends WP_Customize_Control is really crucial: it’s telling PHP that we’re taking the base class that WordPress gives us, and then adding just a little of our own stuff to it. Otherwise the declaration would need to contain a whole lot more.

The code above also shows something that all “custom customizer controls” ( :) ) share: their own render_content() method. This render_content() method is how the customizer creates the field that the user interacts with. This field needs to use the object’s id and label properties, and the getter function value(), so that it’s completely rendered with all the necessary stuff to work with the customizer.

Using the Values

Because there are so many possible ways and places that you’ll use the values set through the customizer, it’s hard to cover all of them. As we discussed in our settings and options articles, these values are set in the database, and you simply retrieve them and use them as you’d like. If they’re set using theme_modm you retrieve them with get_theme_mod( 'mod_name' ). If they’re set as an option (also called a setting—the things that go in wp_options), use get_option().

A Very Simple Example

A rather crude, but useful implementation of a background color in a theme could be as simple as:

function wpshout_customize_background()
{
?>
    <style type="text/css">
    body { background-color:<?php echo get_theme_mod('background_color', '#efefef'); ?>; }
    </style>
<?php
}
add_action( 'wp_head', 'wpshout_customize_background');

In this case, we’ve got CSS,so we’re just quickly dumping out the style tags into the header with a direct hook on wp_head. We could discuss the merits of this approach further, but it does work.

There Exists a “Refresh Problem”

By default, the customizer will refresh your theme’s styling by doing a full-frame page refresh. (That is, the default method for 'transport' for customizations is 'refresh'.) This’ll work fine, and is nice enough to get the job done. But if you want professional-level seamlessness, you need to make it so that you’re handling the messaging to your settings via JavaScript/Ajax.

The details for doing this are a bit complicated, and will make a nice “Part II” to this post, so we’ll leave you hanging. If you really must know now, just do some looking into the postMessage transport option for your settings.

Bam! It’s Like Magic!

The customizer is one of the most important and user-friendly improvements to come to WordPress in the last few years. If you’ve never used it before, its object orientation can perhaps be intimidating; but once you get past the (possibly novel) syntax, there’s a lot of power and much-improved user experience compared to crufty old settings screens. Hopefully you’ve got a strong sense of the system’s power, and good grounding in how to start to work with it. Happy hacking!

Image credit: Picturepest


6 Responses

Pingbacks