Note: Everything I’m talking about here, including the code, is in beta mode. It will be subject to change. I’ll update this post after release to fix any code changes that may occur between now and then. I’m releasing this post now so that theme authors can start looking at their themes and thinking about how they might want to change the way they do options pages.

So, WordPress 3.4 has this nifty new feature you can find on the main Theme selection page. It’s a link next to each theme labeled “Customize”. This is the new Theme Customizer, and it’s way cool.

In fact, you can’t see what it does with a simple picture, so here’s a video. It’s available in HD if you want to go full screen. :)

So, now you know what it does, and if you’re a theme author, you’ve probably just gotten some great ideas. Here’s how you can implement those ideas in your theme.

First, note that if you already support the built in Custom Header and Custom Background functionality the WordPress core provides, then those will magically show up and work in the theme customizer. No extra code needed on your part.

Existing Options

Now, the first thing you’ll probably want to do is to take note of how your existing settings in the theme work. You have three main options for theme settings, realistically. I’ll go over them briefly.

1. “Theme mod”. This uses the set_theme_mod and get_theme_mod functions. It’s rare that themes actually use these since I wrote about the Settings API, but it is there and if you use these normally then it is supported by the Theme Customizer (in fact it’s the default).

2. Individual Settings. If you store your theme’s settings in the options table as individual rows, one per setting, then that works fine with the customizer. This is not the preferred way of doing things in themes, however, and not the most common. Still, some themes do this, so if you’re one of them, it’s supported as well.

3. Serialized Settings. This is the way I explained in my Settings API Tutorial and the method recommended by the Theme Review guidelines, as well as the way Chip described in his own tutorial for theme settings. Essentially, you store your settings in an array, then store that array using set_option or get_option, as one row in the database. This method is supported and it’s the way I’ll primarily cover in this article. I’ll briefly mention the other two methods when appropriate.

Once you know how your settings are stored, then you’ll know what to fill in at certain spots in the code. More on this when we get to it.

Object Orientation

Now, the Theme Customizer is very object oriented, and while you don’t necessarily need to understand this to implement the basics of it, you might need to understand it if you’re going to make something completely custom. Just a warning.

First, we’ll look at the left hand side of the customizer screen. Notice that the left hand side is divided into sections. Actually, that’s their name: WP_Customize_Section. In each of these sections is one or more controls; or rather, WP_Customize_Control. Finally, each of these controls one of more settings on the page: aka WP_Customize_Setting.

The Sections organize the controls. The Controls get input and pass it to the settings. The Settings interface with your existing options in the theme.

To make new stuff here for your own custom options, you need to know where to add it. That place is the customize_register action hook.

add_action( 'customize_register', 'themename_customize_register' );
function themename_customize_register($wp_customize) {
	// ... do stuff ...

The function gets a parameter of the main $wp_customize object. This is the interface point where you will do everything like adding sections and controls and such.

Sections

So, first thing to do is to add a section. Here’s one way to do it:

	$wp_customize->add_section( 'themename_color_scheme', array(
		'title'          => __( 'Color Scheme', 'themename' ),
		'priority'       => 35,
	) );

The first parameter is a unique ID for the section that you’ll need later (when you’re putting controls into it). The second parameter is an array of options for the section. Sections don’t have a lot of options, really. You can give them a title, you can give them a “description” if you need some explanatory text in them. The priority setting determines their order in the list.

You can also give sections a “capability” if you have a special case. Generally speaking, most sites require the “edit_theme_options” capability to have users edit this sort of thing, and this is the default capability that the sections use. However, if you have options that anybody can edit, or which should only be managed by administrators, changing this capability will prevent the section from appearing to users who can’t change those settings anyway.

One final thing you can add to a section is a “theme_supports” option. This will make the menu not appear unless the theme supports something. If you’re putting this code in a theme itself, then you already know what the theme supports, so it doesn’t make much sense. The core uses this to not show the header and background options if the theme doesn’t support them.

Settings

Next, let’s configure some settings. Yes, the settings, not the controls. See, the controls need to know what settings they’re changing, so we have to attach the settings up first.

To declare a setting, you do it like this:

	$wp_customize->add_setting( 'themename_theme_options[color_scheme]', array(
		'default'        => 'some-default-value',
		'type'           => 'option',
		'capability'     => 'edit_theme_options',
	) );

In this case, I’ve declared that the setting I’m interested in is in an option, the option is named “themename_theme_options” in the database, and it’s serialized, and the actual array key in there is “color_scheme”. Remember that talk we had before about the Settings API and how you store your settings? This was method 3.

Here’s method 2 (one option per database entry):

	$wp_customize->add_setting( 'themename_color_scheme', array(
		'default'        => 'some-default-value',
		'type'           => 'option',
		'capability'     => 'edit_theme_options',
	) );

And here’s method 1 (using theme_mod):

	$wp_customize->add_setting( 'color_scheme', array(
		'default'        => 'some-default-value',
		'type'           => 'theme_mod',
		'capability'     => 'edit_theme_options',
	) );

This setting basically tells the theme customizer where the option is stored, and how to change it’s value so that your theme displays with the changed option.

Here’s the good bit about this: You’re telling the theme customizer where the option is. You don’t have to change the way the existing option works at all.

You already have a theme options page, right? So somehow, you’re saving those options. And in the theme, it’s reading those options using get_theme_mod or get_option, right? The way the theme customizer works is that it intercepts that call using a filter, changes the option for the previewer case only, and then passes the new option along to the theme. So the theme has no idea that the value it’s getting isn’t in the database, but one the user just selected. That’s the magic trick and why themes don’t have to dramatically change to support this sort of thing. All they have to do to make custom sections is to tell the theme customizer code what options they’re using and how, and it changes those options directly for the previewer.

(Note of clarification here: The “default” setting above should be a default value, not the current value. The difference is a subtle one, but the point is that you don’t actually need to get the current value of the option from the DB and put it in here. The WP_Customize_Setting takes care of all that jazz for you. The “default” is what should be used if the value doesn’t exist in the DB at all.)

There’s one more bit to the add_setting call that we’ll come back to later when I get around to explaining postMessage.

Controls

Finally, we come to the controls. Controls can look one of a lot of ways, obviously. The simplest controls are just checkboxes, or text fields. However, colors are something that change a lot, so there’s color wheel controls too. In fact, WordPress defines a number of possible controls. Let’s go over a few:

A radio selection:

	$wp_customize->add_control( 'themename_color_scheme', array(
		'label'      => __( 'Color Scheme', 'themename' ),
		'section'    => 'themename_color_scheme',
		'settings'   => 'themename_theme_options[color_scheme]',
		'type'       => 'radio',
		'choices'    => array(
			'value1' => 'Choice 1',
			'value2' => 'Choice 2',
			'value3' => 'Choice 3',
			),
	) );

Pretty simple. It’s referencing the section it’s in, the setting that it’s going to change, and then it has the radio type and the list of choices along with their associated values.

How about a checkbox instead? This one comes straight from core:

	$wp_customize->add_control( 'display_header_text', array(
		'settings' => 'header_textcolor',
		'label'    => __( 'Display Header Text' ),
		'section'  => 'header',
		'type'     => 'checkbox',
	) );

A checkbox is on or off, true or false. It needs no real values.

How about a selection dropdown box? Here’s an example:

	$wp_customize->add_control( 'example_select_box', array(
		'label'   => 'Select Something:',
		'section' => 'nav',
		'type'    => 'select',
		'choices'    => array(
			'value1' => 'Choice 1',
			'value2' => 'Choice 2',
			'value3' => 'Choice 3',
			),
	) );

The default type of control is actually type = ‘text’, and it creates a text box control. One more type of control is the “dropdown-pages” type, which creates a dropdown list of the WordPress Pages.

But that’s not all. There’s actually several more, but because they’re so custom, they’re declared differently. Here’s where we get all object oriented on ya…

	$wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'link_color', array(
		'label'   => __( 'Link Color', 'themename' ),
		'section' => 'themename_color_scheme',
		'settings'   => 'themename_theme_options[link_color]',
	) ) );

Whoa, what’s with the new class? The WP_Customize_Color_Control is a class that is extending the built in WP_Customize_Control class. It adds the color wheel jazz to places where color selection is needed. Note that the class is being created here with new, and so it has to get the $wp_customize passed to it directly, so it knows where to hook in. (Note: This may change before final 3.4 release.)

Other controls of note:

  • WP_Customize_Upload_Control – This gives you an upload box, for allowing file uploads. However, you probably won’t use this directly, you’ll extend it for other things… like:
  • WP_Customize_Image_Control – This gives the image picker and the uploader box. It extends the upload controller. You can see it in action on the custom background piece, where a user can upload a new file to be the background image.
  • WP_Customize_Header_Image_Control – Because of the resizing action of the header piece, it needs a bit of special handling and display, so the WP_Customize_Header_Image_Control extends the WP_Customize_Image_Control to add that functionality. You can see it in action on the custom header piece, where a user can upload a new file to be the header image.

So, the way to create a custom controller to do whatever you want is to make a new class of your own which extends WP_Customize_Control and adds the bits you want. How to do that is a bit complex, so I’ll save that for another tutorial. For now, you’ve got image handling, color wheels, text boxes, radios, dropdowns, and checkboxes. I think that should be enough to get started with.

End of tutorial?

Not quite. Everything I went over above is enough to add new sections to the customizer, put controls in them, and then to have the preview show your changes after a slight delay when the page refreshes. All you have to do is to call those functions with the proper parameters, in the proper place, and it’ll work.

However, note that I said “when the page refreshes”… C’mon… this is the year 2012. We don’t have flying cars, and we still have to wait a whole second or two?

Nope.

Enter postMessage

Back when I mentioned the $wp_customize->add_setting function call, I mentioned “one more bit”. That one more bit is the option called “transport”.

Transport defines how your setting change gets from the place where you changed it into the preview pane. The default setting for this is “refresh”. An alternative setting is named “postMessage”.

The postMessage transport makes it such that the setting is instantly sent into the other frame, where javascript can adjust the page on-the-fly using this new information.

An example:

Let’s say we have a setting to change the colors of the titles. All the titles on the page are in some tag that has a class of posttitle, perhaps. The option normally just saves the HTML color chosen, then outputs some inline CSS in the header.php to basically do this:

.posttitle {
	color: #abcdef;
}

Or whatever the option actually is for that color.

We have hooked our setting to that option, and hooked our WP_Customize_Color_Control up to it, and now when we change it, it works and we can see the color change. Note that this is easiest to do with already working customizer options, so the best way to do it is to get it working normally first, then add on this next bit.

Now, we have the working option in the customizer, so to take away that refresh delay, we’ll add this new option to the add_setting call:

	'transport'         => 'postMessage',

This tells the customizer that the setting will be sent directly to the frame via javascript. However, for that setting to work, we need javascript in the frame itself to receive it.

So, back in our main function… remember that? It started like this:

add_action( 'customize_register', 'themename_customize_register' );
function themename_customize_register($wp_customize) {
	// ... do stuff ...

Right at the end of that function, we’re going to add this code:

	if ( $wp_customize->is_preview() && ! is_admin() )
		add_action( 'wp_footer', 'themename_customize_preview', 21);

This is going to add a new function call to our preview frame’s footer. It only gets added with the preview frame, so the live site and others won’t see it, because they don’t need to see it. This is where we’re going to output our javascript to make things happen in real-time.

Here’s our function:

function themename_customize_preview() {
	?>
	<script type="text/javascript">
	( function( $ ){
	wp.customize('setting_name',function( value ) {
		value.bind(function(to) {
			$('.posttitle').css('color', to ? to : '' );
		});
	});
	} )( jQuery )
	</script>
	<?php 
} 

As you can see, it just outputs a bit of javascript. This code won’t change much, ever, so let’s go over just two pieces of importance:

  • ‘setting_name’ is the name of the setting, as added by the $wp_customize->add_setting call.
  • The entire line starting with jQuery(‘.posttitle’) is our custom bit of code. It gets the “to” variable, which will be the color chosen by the user, and it sets the posttitles on the page to have that color, using the css modifying functionality of jquery.

Those are the only two bits you need to change, really. The rest is pretty copy-pasta. For each real-time setting, you can dupe this bit of code in the script.

Here’s another thing: You can change pre-existing refresh settings to be postMessage ones. Take the Site Title and Tagline elements in the Header section, for example. These are refresh settings, and the reason they are is because each theme implements them differently. There’s no way for the core to know the javascript code needed for any particular theme.

But if you’re a theme author, then you’re not writing for a generic theme. You’re writing for your particular theme. You know how the site title and tagline are displayed. There’s no reason you can’t make those update in real time. And while you’re at it, the header_textcolor setting can be real time too, since you know the theme code.

In your main function again, add these three lines of code:

	$wp_customize->get_setting('blogname')->transport='postMessage';
	$wp_customize->get_setting('blogdescription')->transport='postMessage';
	$wp_customize->get_setting('header_textcolor')->transport='postMessage';

That changes the transport on those core settings to be postMessage. Now you need to add the javascript code to actually do the refreshing in your theme. Here’s an example of TwentyEleven doing this (with the patch I wrote for it):

function twentyeleven_customize_preview() {
	?>
	<script type="text/javascript">
	( function( $ ){
	wp.customize('blogname',function( value ) {
		value.bind(function(to) {
			$('#site-title a').html(to);
		});
	});
	wp.customize('blogdescription',function( value ) {
		value.bind(function(to) {
			$('#site-description').html(to);
		});
	});
	wp.customize( 'header_textcolor', function( value ) {
		value.bind( function( to ) {
			$('#site-title a, #site-description').css('color', to ? to : '' );
		});
	});
	} )( jQuery )
	</script>
	<?php
}

For the blogname, it changes the HTML inside the “#site-title a” link. For the description, it changes the tag with #sitedescription. For the color of those, it simply targets both of them and alters their CSS.

Core has to try to be generic across all themes. But themes have more knowledge of how they work and can change things to target themselves in better ways. A theme adding controls knows what those controls change, so if it’s something simple like CSS or even something more complex like HTML, if you can write javascript code to make that modification in real time, then you can use postMessage and eliminate that refresh delay.

Hopefully this explains some of the theme customizer. Was it as clear as mud? Take a look at my patch to Twenty Eleven to add some of the theme options from its existing options screen into the customizer. You can find it on this ticket: http://core.trac.wordpress.org/ticket/20448.

Shortlink:

242 Comments

  1. Very nice work, Otto. Everyone who has worked on this has done a great job. Thanks for the details in this post.

    I do have a question: I have trunk running locally, and it *appears* that the auto-previewing isn’t working. I tested with your patches to TwentyEleven and I saw the same thing on the color scheme chooser (it doesn’t work atm). Is this true, or do I have a bug somewhere?

  2. Wow Otto & Koop, nice work! I had no idea this was being worked on for WordPress core. How great!

    I’ve been doing some similar things in the Styles plugin: http://wordpress.org/extend/plugins/styles/

    It seems like there’s a lot of overlap (image selectors, color pickers), as well of some things I might be able to contribute (gradient pickers, configuration based on the theme’s style.css). Is there anything I can do to help with what you two are doing?

  3. Nice post! We managed to figure this out last week thanks to Koop and Zao…. the new base theme for the WP e-Commerce Plugin is going to be sweet because of it :)

  4. Thanks for writing a tutorial on this. It’s really helpful to read a long-form explanation of how it all works. Hoping to wire it up to the Options Framework plugin this week and test it out.

  5. Awesome work otto, worth sharing this article…

  6. Is there any way to save the color options with the #?
    Seems the color setting is just the hex code only.

  7. Will it work on all themes or only on twenty eleven?

  8. WoW! I think I even understood all (most?) of that … great write up! I missed that whole part in Trac about themes with options having to add WP_Customize controls, etc.

  9. I wasn’t really excited by this at first, but seeing that it’s extensible by theme authors and realtime updating is built in changed my mind… very cool… thanks for explaining it.

  10. Hi Otto

    Your tutorial helps my understanding very much.

    It seems that the following errors will come out if a blog is displayed although I tried this code.

    Fatal error: Call to a member function is_preview() on a non-object in /.../wp-content/themes/raindrops/functions.php on line 66

    I’m change your code

    if ( method_exists($wp_customize,'is_preview') and ! is_admin() ){
    add_action( 'wp_footer', 'mytheme_customize_preview', 21);
    }

    It seems work properly.

    is this change is appropriate ?

    Thank you.

  11. [...] want to give big props to Otto for providing a thorough explanation of the implementation details for developers (which is currently subject to change, since it is beta code, after all). It’s a helpful post [...]

  12. [...] TweetHow to Leverage the Upcoming Theme Customizer in WordPress 3.4 Check out this cool overview that gives you a look inside the Theme Customizer coming out with WordPress 3.4. The process of setting up and previewing a new theme is completely streamlined and oh-so sleek. This definitely gives theme developers everywhere something else to think about when developing their themes. Making WordPress easier for the user? We approve. [...]

  13. [...] that you’ve seen the video, head on over to Otto’s incredibly detailed post on how to bring support for the new customizer into your own themes. Hello there! If you are new here, you might want to subscribe to the RSS feed for updates on this [...]

  14. [...] O tema precisa ter suporte a esta ferramenta, caso contrário, ela não funcionará. O próprio Otto explica como preparar o seu tema para o Theme Customizer. [...]

  15. This is really exiting feature, Have seen this first time, Love to implement in my own site.
    ~rakesh kumar

  16. [...] to leverage the Theme Customizer in your own themesHow to leverage the Theme Customizer in your own themes by Otto Wood, who is a WordPress core developer. Get your theme ready for [...]

  17. Played around with this and was able to pretty much copy and paste (like you said). So, cool.

    One thing I noticed, though, is that the refresh doesn’t happen when you click Save.

    • Saving just saves. The refresh or postMessage on the preview pane happens when the change in the control is actually made. So by the time you hit save, you’ve probably already refreshed at least once and seen the change. No need to refresh again on save.

  18. Hi, amazing job!
    I would like to know, is there any way to add Google Fonts to theme customizer? You could choose the font from the list, and see in the preview, how it looks on the page. Can it be done without modifying wordpress core files?

  19. [...] is a lot to say about this feature, and I’ve only started scratching at its surface thanks to Otto’s excellent tutorial, but as you can see from the grab this feature allows theme developers to add in their own theme [...]

  20. [...] How to leverage the Theme Customizer in your own themes » Otto on WordPress [...]

  21. [...] Otto’s tutorial on how developers can leverage the Theme Customizer [...]

  22. I might have found a bug w.r.t. the postMessage concept on IE8. If I have JS code in the customization previewer function (hooked via wp_footer), it seems to throw an error saying that wp is not defined. Have you come across this?

    • Nope. But, if you have JS on the page anywhere that is broken, then parsing will stop and the customize code may not get defined properly. The page does have to be working correctly for JS to work.

  23. Awesome new feature. I’m wondering, is there any way to specify a page template that a set of options applies to? I imagine that the previewer only shows the home page of the site. Say I have some options that apply to a subpage template. Is there any way to preview those?

  24. Hi Otto,

    great write up about this awesome new feature!! Thanks a lot.
    I’m really looking forward for another tutorial you mentioned in your post, about extending WP_Customize_Control with custom Classes.
    I had some success in extending it, but some clear words about it would help a lot ;-)

    Can you tell a vague date when (or even if) your are planning to release such a tutorial?

    thx..

  25. What is the easiest way to reset if you messed something up on the code and can not figure out what you did?

  26. [...] With the enhanced theme control, you’ll be able to make adjustments to your theme’s options and settings before actually activating the theme on the front-end of your sites. This is made possible with the additions of the Theme Customizer and Theme Previewer. Theme Customizer will also be bringing a new and more interactive way for theme options to be used. You can watch an overview of this new feature as it was in WordPress 3.4 Beta on Otto’s blog, where he explains how to leverage the Theme Customizer in your own themes. [...]

  27. [...] With the enhanced theme control, you’ll be able to make adjustments to your theme’s options and settings before actually activating the theme on the front-end of your sites. This is made possible with the additions of the Theme Customizer and Theme Previewer. Theme Customizer will also be bringing a new and more interactive way for theme options to be used. You can watch an overview of this new feature as it was in WordPress 3.4 Beta on Otto’s blog, where he explains how to leverage the Theme Customizer in your own themes. [...]

  28. [...] you can check the details here. Surely this functions are unavailable by default, you need to alter the functions.php and I think [...]

  29. [...] of this new feature as it was in WordPress 3.4 Beta on Otto’s blog, where he explains how to leverage the Theme Customizer in your own themes.Custom HeadersUp until now, uploading a header image for a theme using WordPress’ built-in [...]

  30. [...] With the enhanced theme control, you’ll be able to make adjustments to your theme’s options and settings before actually activating the theme on the front-end of your sites. This is made possible with the additions of the Theme Customizer and Theme Previewer. Theme Customizer will also be bringing a new and more interactive way for theme options to be used. You can watch an overview of this new feature as it was in WordPress 3.4 Beta on Otto’s blog, where he explains how to leverage the Theme Customizer in your own themes. [...]

  31. [...] With the enhanced theme control, you’ll be able to make adjustments to your theme’s options and settings before actually activating the theme on the front-end of your sites. This is made possible with the additions of the Theme Customizer and Theme Previewer. Theme Customizer will also be bringing a new and more interactive way for theme options to be used. You can watch an overview of this new feature as it was in WordPress 3.4 Beta on Otto’s blog, where he explains how to leverage the Theme Customizer in your own themes. [...]

  32. Hmmm, I’m having a few headaches trying to get the radio boxes working. It doesn’t seem to be sending the selections through to WordPress. If anyone else is having this problem, please get in touch so I know I’m not the only one :)

  33. Hello great post
    Is there a way (general option or property of WP_Customize_Manager/ WP_Customize_Control classes) to prevent images to be saved in Media Library when Customizer not saved?

    I explain :), after some trials, adding derived classes etc… I had a look to the media Library, it was full, full ful, full of images and textures I tested in the customizer preview window but never saved and published.

    As all images are not attached, I can’t say which ones are used, which ones are not used.

    Did I miss something?

    • No, uploading an image is a separate operation. In order for the image to be displayed and known about, it has to be in the media library.

      • It means that depending on how many tries we do, Media Library will be filled with useless files. It is explained nowhere and I think many will be surprised.
        The uploaded tab of WP_Customize_Image_Control is keeping a list of uploaded files, maybe a cleanup could be done when saving or leaving.

        Other topic: How to add a control binding to a section settings inside a tab of a extended WP_Customize_Control.

        and last :) How to add a link to Media Library in a WP_Customize_Image_Control

        Sorry for my english, it is not my native language.

  34. That’s pretty cool. However, my biggest problem is that clients have the option to change themes. Let me be blunt, most clients should not be changing the style of the theme. It’s a total nightmare to deal with wannabe Da Vinchis. I wish WordPress would split into two tracks with their themes. One track would have options like the one Otto is working on. The other would be for developers. It would be barebones and have no theme style options. I am aware that there are themes like this already, but I would like an “official” barebones theme. That way, you could get a lot of people supporting the theme and guaranteeing it is bug free. A lightweight 2012 developer theme would speed up development time for people who actually make money designing/developing WordPress sites for clients. You could have a lightweight 2012 “developer” (no injected css, or any unnecessary code) version, and 2012 “regular” version.

    • It’s their site. They have the right to control how it looks, behaves, and works. If they want to switch themes, then that’s up to them. Web developers and designers who try to take all the control away from their clients are the real problem here.

      WordPress isn’t here to support you or your business in creating websites for clients, it’s here to allow the user to create websites themselves, to enable anybody to be capable of publishing to the web. Your notion of somehow making it easier for you to control the client is fundamentally at odds with this WordPress philosophy. IMO, of course.

      • I think you’re confused with what I’m saying. If someone wants to take the time to host their own blog and learn how to use the site interface, then the customization options shown here are awesome. I’m talking about making a separate track for the default themes that would be for developers. All the customization could be added to this base framework to create the regular 2012 theme. Have you ever created a child theme for 2012? I have to write a bunch of custom functions just to cancel out all the code that WordPress injects into the site just to get my site to work how the client wants it to look.

        A developer theme would allow rapid prototyping. This is good for user’s of WordPress. It could also simplify the backend UI. Some of my clients will take a look at the backend, see all the options and run away screaming. This hurts blogging, because some clients simply don’t want to deal with customizing their sites, or they break their sites when randomly clicking buttons. This costs money and hurts blogging in general. I want to emphasize that many people aren’t CS majors, and the options that seem simple to you can result in a tyranny of choice for the people that pay me money to help them. I am merely suggesting that WordPress development take real life into account. I’m merely suggesting solving a problem that, in my mind, seems rather simple to solve.

        • Yes, I understand what you’re saying, but I disagree.

          The solution is simple: if you think you can make a better theme, then make a better theme. The default themes are VERY light on options, IMO. So, if they’re not to your suiting, then build what you think works and use it.

          This is open-source. Better code wins. Show me the code.

          • I have already made a better theme and would be happy to submit it. However, my theme also overrides a number of inherent functions in setup of WordPress. So I am overwriting a lot of things that WP is trying to set up for me. Do a search for all the people who are trying to change HEADER_IMAGE_WIDTH on Google. It’s crazy that developers have to fight WP just to get their themes to work, when they are going to put up their own header with CSS.

            I’m not trying to knock what you’re doing Otto, I think it is great. Many people will use it and I think it’s fantastic. However, I am talking about a slightly different subject. I see a need for developers to rapidly take a site in HTML and CSS and port it to WP without having to fight WP internals. I would be surprised if WP would accept my suggested changes because it would result it a philosophy change in the way themes are doled out. It would require WP to be more modular.

        • We just remove some privileges to clients. If oyu have a client that wants a trim backend that is easy to understand, then just give them that. WordPress gives you the ability. For example, at inswebsites.com we our clients have a user Role that gives them abilities to change most of their site content, but not Themes or Plugins or even Widgets. The new Theme Preview is not going to be an option for any user that does not have the switch_themes capability. Eli, I think you are doing it wrong.

        • Otto, thanks for this! Any idea when we may see something in the Codex?

  35. Way cool feature. Should be out this week i hope

  36. [...] Theme customizer: This is a really sweet addition for WordPress.com users that adds a very slick WYSIWYG to your theme editor that allows you to design your theme on the spot and then watch the updates happen in real time instead of having to refresh browser windows every time you change the color or misspell a title.  However, this won’t affect you much if you’re using a custom theme.  Unless your theme makes use of the following from Otto’s post. [...]

  37. I searched for this post for like half an hour. I was about to create a new theme and now wordpress has a really great option, would use it in the theme development from now on.

  38. [...] hope that more developers start using this instead of complex theme options. Otto has a great article that will show you how to leverage the theme customizer in your themes. Check out the video walk [...]

  39. [...] enhances the ability to improve your site on the fly.  There is an excellent article by Otto on using the new WordPress sizable headers which will help in understanding how this new feature [...]

  40. [...] of the customizer from a developer’s perspective, I couldn’t do a better job than Otto did in his post on the topic.Child themes in dot org and via theme installerChild themes are now supported via the theme [...]

  41. Is there a way to manipulate or remove standard entrys like “Site Title & Tag Line” or “You are Previewing” from the sidebar?

  42. Refresh works just fine, but I can’t seem to get postMessage working. Any tips on why that might be happening? I have quite a few wp.customize functions, stored as individual settings (and also available in an array), and a function creates settings and controls through a foreach. Most of the settings are colors, but I also have font-related settings.

  43. [...] activate your newly edited theme. There’s a great article that shows just how to utilize the theme customizer in your themes – Otto goes into great detail about this new tool and has some great content [...]

  44. Hey Otto,

    We’ve added support to the customizer for a number of our themes, and I’ve hit one issue with IE and postMessage. Because IE runs inline JavaScript before it is added to the DOM (seriously), the following code wouldn’t work for me (kept getting a ‘wp’ is not defined error in IE):

    function themename_customize_preview() {
    	?>
    	<script type="text/javascript">
    	wp.customize('setting_name',function( value ) {
    		value.bind(function(to) {
    			jQuery('.posttitle').css('color', to ? '#' + to : '' );
    		});
    	});
    	</script>
    	<?php 
    } 
    

    So far, the only solution I’ve found is using the ‘defer’ attribute like so:

    function themename_customize_preview() {
    	?>
    	<script type="text/javascript" defer="defer">
    	wp.customize('setting_name',function( value ) {
    		value.bind(function(to) {
    			jQuery('.posttitle').css('color', to ? '#' + to : '' );
    		});
    	});
    	</script>
    	<?php 
    } 
    

    This seems to work in Internet Explorer for me. If you’re loading the postMessage JS as a separate external file, you won’t hit this issue (as seen in TwentyEleven). This IE JS stuff is totally new territory for me, so feel free to call BS if I’m way off the mark and there is an easier solution.

    • Twenty Eleven’s code actually works because they’re wrapping the code inside this:

      ( function( $ ){
      // wp.customize stuff here
      } )( jQuery );
      

      That’s the right way to do it, which I didn’t really go into great detail about in the post. This prevents the code from running until the DOM is fully loaded, and where the wp will be defined. Nothing to do with being an external file or not, really.

      • Try printing that JavaScript directly to HTML instead of loading it in an external file. If the jQuery library isn’t cached by IE9, it will report a ‘jQuery not defined’ error because (as far as I can tell) IE isn’t waiting for jQuery to be loaded before executing that bit of JS.

        Try replacing the last function in theme-options.php in TwentyEleven with this to see what I mean.

        /**
         * Bind JS handlers to make Theme Customizer preview reload changes asynchronously.
         * Used with blogname and blogdescription.
         *
         * @since Twenty Eleven 1.3
         */
        function twentyeleven_customize_preview_js() {
        	?>
        	<script type="text/javascript">
        	( function( $ ){
        		wp.customize( 'blogname', function( value ) {
        			value.bind( function( to ) {
        				$( '#site-title a' ).html( to );
        			} );
        		} );
        		wp.customize( 'blogdescription', function( value ) {
        			value.bind( function( to ) {
        				$( '#site-description' ).html( to );
        			} );
        		} );
        	} )( jQuery );
        	</script>
        	<?php
        }
        add_action( 'wp_footer', 'twentyeleven_customize_preview_js', 30 );
        

        When I go to the preview screen, I’m unable to see the Site Title auto-updated. Is it something with my setup?

        • I have the very same error with IE9 too. For some wrong reason, IE9 did run the inline script first. Move the script to external js works fine, but in my case, I need it inline as I load the options dynamically.

          So in that case, I rely back on browser window.onload event, instead of using jQuery.ready event. Wrapping the code and run it on window.onload solve this issue on IE9. :)


          window.onload = function(){
          // wp.customize stuff
          }

          Hope that helps!

          • Thanks Jeffri – window.onload definitely works as well. I’m glad I’m not the only one hitting this problem – I *totally* didn’t realize IE did this.

          • I just wanted to say I experienced this exact issue, as well.

            I had setup many options and I was using postMessage for all of them. Everything worked in all standard browsers on my Mac (Firefox, Chrome, Safari), and then I went to test on a PC in IE9, and noticed none of my javascript was working within the preview window.

            I used the IE9 Developer tools and viewed the Console tab. You can see this error in the screenshot below.

            Screenshot: http://picturestack.com/923/33/XuxScreenShotsWb.png

            I was able to fix with Jeffri’s suggestion also.

  45. I dont get it..

    so you paste the code into the functions.php?

    like:

    add_action( 'customize_register', 'themename_customize_register' );
    	function themename_customize_register($wp_customize) {
        	$wp_customize->add_section( 'themename_color_scheme', array(
    		    'title'          => __( 'Color Scheme', 'themename' ),
    		    'priority'       => 35,
    		) );
    	
     // ... more stuff ...
    	}
    
  46. Nice article.
    is it possible category dropdown like pages ( type => dropdown-pages ) ???

    • You can do it like this:

      $wp_customize->add_setting('themename_theme_options[page_test]', array(
          'capability'     => 'edit_theme_options',
          'type'           => 'option',
      ));
       
      $wp_customize->add_control('themename_page_test', array(
          'label'      => __('Page Test', 'themename'),
          'section'    => 'themename_color_scheme',
          'type'    => 'dropdown-pages',
          'settings'   => 'themename_theme_options[page_test]',
      ));
  47. Oops! Thought you were looking for dropdown-pages not categories :) You can list the categories by doing something like this:

    $categories = get_categories();
    $cats = array();
    foreach($categories as $category){
        $cats[$category->slug] = $category->name;
    }
    
    $wp_customize->add_setting('abfolio_theme_options[header_select]', array(
        'default'        => 'value2',
        'capability'     => 'edit_theme_options',
        'type'           => 'option',
    
    ));
    $wp_customize->add_control( 'example_select_box', array(
        'settings' => 'abfolio_theme_options[header_select]',
        'label'   => 'Select Something:',
        'section' => 'abfolio_site_options',
        'type'    => 'select',
        'choices' => $cats,
    ));
  48. Otto Great Post, thanks for taking the time to share it with everyone.

    I have a quick question about using custom controls. I have a bunch of registered_settings in the admin and I call specific color pickers, and dropdown menus etc… They are all prebuilt so what’s an easy way to display these controls instead of using WP’s defaults like ‘radio’.

    Just a shove in the right direction would be great. I get that I have to create a new class extending $wp_customize but not seeing the next step.

    thanks

  49. Is it just me or does

    $wp_customize->add_section( 'themename_color_scheme', array(
    	'title'          => __( 'Color Scheme', 'themename' ),
    	'description' => __( 'Testing descriptions', 'themename' ),
    	'priority'       => 35,
    ) );

    not work?

    • Just you, I think. That code seems fine to me. Gotta have it in the right place, of course, but nothing wrong with it.

      The “description”, BTW, shows up as the title attribute of the H3 which holds the title. It’s not actually displayed. See the render() function in class-wp-customize-section.php. If you need to actually display something there, you can use the customize_render_section actions called by the maybe_render function.

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Need to post PHP code? Wrap it in [php] and [/php] tags.