How to leverage the Theme Customizer in your own themes
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.
Otto, excellent article, are you planning to write the advanced one soon “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. ”
I was trying to build a customised version of radio buttons that use images as pickers rather than the button/text. I started by trying to build my own ‘extends WP_Customize_control’ by taking WP_Customize_Image_Control as an example, but I got a bit lost. I’m sure with the insight of an advance tutorial I might be able to get that sorted. For the time being I guess a bit of image html in the ‘radio’ choices will be an approximation.
Keep up te good work.
@ Alan Fuller Did you ever have any luck with the images and radio buttons?
Any html that I enter into the string for my radio button just comes out as plain text. Is there a way around this?
Oh dear, my plan of adding html to the image choices fails, as it seems it gets displayed as pure text. Another cunning plan would be to use css, but unfortunately each of the radio buttons don’t have a unique class or id. So it looks like I’m stuck with raw text until I can get to grips with extending the classes.
I’m rather confused as to how to get this to work….
I’ve created a theme-options.php an am including it in my functions.php like so
require_once ( ‘library/theme-options.php’ );
Then in the theme-options.php i have the following:
add_section( ‘themename_color_scheme’, array(
‘title’ => __( ‘Color Scheme’, ‘themename’ ),
‘priority’ => 35,
) );
$wp_customize->add_setting( ‘color_scheme’, array(
‘default’ => ‘some-default-value’,
‘type’ => ‘theme_mod’,
‘capability’ => ‘edit_theme_options’,
) );
}
?>
but nothing shows up when i customize the them in the customizer. Sorry for the noobishness, i’m no php programmer.
-jeremy
Nevermind i was being a Renob. I wasn’t calling my add_control and my variables were messed up. I got it setup.
After some modifications, it works beautifully 🙂
in my theme-options.php
I must be missing a step i have to do before i do all of this, correct me if i’m wrong, this is for getting your “options” to show up in the customizer, But don’t i have to do some steps before this about declaring the colors etc using add_theme_support() or something like that?
Hi Otto. This all looks great, but I think I’ve reached a potential bug, and i hope you can enlighten me if that’s not the case.
I use one database option to store all my options (the serialized method), but that doesn’t seem to play 100% nice with the js postMessage thing.
This code:
wp.customize( 'my_options[option_name]', function( value ) {
console.log(value());
value.bind( function( to ) {
$( 'body' ).html( to );
} );
} );
always outputs value() in the console, but somehow if the option is a serial one the javascript that should update thins without refreshing does not work.
The same identical scenario as above works if I have a single option:
wp.customize( 'blogname', function( value ) {
console.log(value());
value.bind( function( to ) {
$( 'body' ).html( to );
} );
} );
Is this a known issue?
The “value” isn’t what you think it is. You need to log the result of the “to” variable.
Wow, that was fast! Thanks.
Yes, I tried it, what I implied (sorry for the ambiguity) was that the inner bind function doesn’t run at all.
i.e. this
wp.customize( 'my_options[option_name]', function( value ) {
console.log(value());
value.bind( function( to ) {
console.log('do I run? if yes what is the value of "to"? easy, it is > ' + to);
$( 'body' ).html( to );
} );
} );
only outputs the first log, the second does not run, it isn’t just that ‘to’ doesn’t have the value I would expect, I don’t even know what it is.
and, not sure if this is relevant, the data-customize-setting-link attribute on the field is “my_options[option_name]” too
Maybe the filter that hijacks the updated form field is not being able to emulate the writing of a serialized option?
i.e. (I have no idea of how it works) if the filter has to emulate a single option update it can, but if it has to parse that option and update one of the inner options it can’t?
What is “value()” supposed to be? Just remove that line entirely.
Sure.. I can remove it, I was just trying to see whether there was any way to have javascript output what i was typing in the form field, since the body on the right was not being updated with the new value. As I said I am just a bit lost on the “why the same identical code works with a single option but it doesn’t with a serialised option 🙂
No, I mean, “value” isn’t a function. “value()” makes no sense, and may stop JS execution.
When I log console.log(value) there console gives me this back.
But anyway, I removed it and tried, same issue. To be 100% sure I just tried this test code in this exact same environment:
$wp_customize->add_setting( 'single_test', array(
'default' => '',
'type' => 'option',
'capability' => 'edit_theme_options'
) );
$wp_customize->add_control( 'single_test', array(
'label' => 'Single Test',
'section' => 'test_section',
'settings' => 'single_test',
'type' => 'text',
'priority' => 999
) );
$wp_customize->get_setting('single_test')->transport='postMessage';
then added this as javascript:
wp.customize( 'single_test', function( value ) {
value.bind( function( to ) {
$( 'body' ).html( to );
} );
} );
and it works perfectly
Did you ever find a solution? I am trying to use the customizer with theme options as well, IE: themeoptionsname[link_color] and the live preview doesn’t work.
Unfortunately I didn’t, and I am considering switching to single wp_options db entries because of it.
I am creating a github repository that showcases the problem so I can send the link to Otto and the rest of the dev team. If there is in fact a “bug” or an issue with the customizer of some sort, they will definitely have an easier time catching it with a live example/case study 🙂
[…] in the first tutorial, I talked about the various controls available in the customizer. Specifically I mentioned image […]
Hey Otto –
Awesome writeup and job on this. We have implemented an extensive color selection via the customizer in a new theme but cannot seem to find a way to clear or reset. Does this functionality exist or can it easily be done? (There is no default tab on the color picker for peeps to revert to the default for some reason)
I am also having this problem.
Same issue, need to be able to reset to defaults so that options are not in the DB. Anyone figure out how to do this?
The latest version of WordPress includes a reset button on the theme customizer color picker controls.
Thanks David. Not quite what I was looking for but helpful. I actually wanted to make a “reset all” button, which I have about 90% there now 🙂
Hey Otto,
Is it possible to have multiple instances of these options, so that presets could be created for the user to choose from?
Did you figure out how to have multiple instances?
[…] For those interested in finding out more here is a link to a great article on “How to Leverage the Theme Customizer in your own Themes” […]
[…] Theme and plugin developers interested in adding new options to a theme’s Theme Customization page should see the documentation on the Theme Customization API. Additional tutorials on the Theme Customization API are available at the Ottopress.com website. […]
Anyone have an issue with the controls not displaying in the order they are created? I can’t seem to find any common reason for their ordering and they seem to be different based on the order I declare them
You can pass a ‘priority’ argument inside the array you pass to add_control().
I realized that about 10 seconds after I posted this 🙂 Thanks for your help
Did you get this to work for you Jesse?
[…] “squeeze” their options into the customizer, which is great. And there’s a great tutorial by Otto showing you how to do that. Thanks […]
Excelent post, but how did you use saved customized settings? Do you need to create new method which will be used to generate css for example and put it in the header or what?
add_action( 'wp_head', 'my_customized_style' );
function my_customized_style()
{
echo (''.get_setting('setting_name').'');
}
?
You use the settings the same way you used the same settings before. That bit doesn’t change.
If you already had a settings page, then you must have already been using the settings in some fashion. This doesn’t affect that. In the next post, I go into how to make a theme without a settings page and using this and the theme_mod methods.
I can see how this works to make an individual colour change, but what if you want one option to affect multiple changes in the css? E.g. option “blue” = dark blue h1 tags, light blue h2 tags and a white text on a blue background for the menu.
If your pre-existing option already does that, then it will just work without any special handling. The reload process will reload the page inserting your option in as if that was what it was already set to, so any PHP code you have to generate the color changes will take effect.
If you’re wanting to make it “real-time” using postMessage, then you’d simply write your JS code so that it changes all the affected elements one by one.
The JS I have for examples in the post only affect one thing each, but there’s no reason they can’t affect more than one thing. For example:
(Note, this code is an example, not necessarily working code. Fiddle with as needed.)
You would need 3 options for these, with a setting and control each, so one for the headings link color, one for the menu background, and one for the menu links. Then in your javascript section, you have three items for each defining the selectors, ie:
When building your style.php, you can use multiple selectors at once per normal practice:
Great post Otto, I got it working now!
One thing I would like to change, but can’t figure out how and if it’s possible:
– When closing the preview, we get a redirect to themes.php – is there anyway to redirect to another page (my theme options page)
That would be great!
Thanks, Sander
P.S. If it’s not possible, I would also be happy to have an action_hook áfter the settings are saved. Now there’s only one before saving 🙁
the script customize.php takes an optional argument ‘return’ e.g. /wp-admin/customize.php?return=themes.php?page=theme_options
so if you can modify the link that the customizer is being called from then you can do this fine.
That’s great, it works perfectly! Thank you very much Alan! 🙂
Hey Otto, great tutorial – I’ve used some of this in a theme I’m designing.
I do have one question for you though: when using WP_Customize_Color_Control is there any way to go back to the original, default color (i.e. the one defined in the Theme’s stylesheet)?
[…] based on user selections. Otto has a couple of really good articles on how to use it. The first, How to leverage the Theme Customizer in your own themes, is a good introduction to the customizer. I was happy find that there’s even Javascript that […]
Hey Otto,
Great article thank you. I’m using serialized custom theme options, and it appears that when I add/hook-up custom checkbox fields, they work properly but ALWAYS load in the “checked” state, even though the HTML properly includes/doesn’t include the “checked” attribute…some JS appears to be automatically marking all them as checked, but I don’t have any custom scripts :/
As I mentioned, they are hooked up to the underlying options properly, and checking and unchecking is reflected in preview-mode. Any ideas what might be causing this/what I’m doing wrong? I browsed the customize-base script, but nothing popped out…
Thanks in advance!
I’m seeing exactly the same behavior when trying to implement a checkbox as Ian has. Any suggestions?
This was resolved for me when I made sure the ID used in $wp_customize->add_control() was unique.
Cool, really cool. Looks like I miss a lot of new WP features.
[…] had a series of articles highlighting how to use the theme customizer in your WordPress themes instead of […]
[…] has been introduced in WordPress 3.4, and although Twenty Twelve doesn’t create its own custom settings in the customizer, it adapts very nicely to the existing ones, by setting their transport to postMessage and handling […]
Otto, I was having trouble getting the real-time previewer to work (i.e. with ‘transport’ => ‘postMessage’). I tracked it down to this line:
$('.posttitle').css('color', to ? '#' + to : '' );
When echoing the color value out to the browser console it was appearing with a double ‘##’ prefixing the color value. So I just changed the code to the following which works fine:
$('.posttitle').css('color', to );
Should there definitely be a check in there for the ‘to’ value though? If so should it be something like this:
$('.posttitle').css('color', to ? to : '' );
When I first wrote this, the color came out of the picker without the #. I believe they standardized it to behave differently in the final version, so the code may vary slightly from when I wrote this post.
[…] Using the theme customizer in your own themes […]
I understand how preview refresh when transport is postMessage and I used it successfull with some custom controls, but I don’t understad how preview iframe refresh when using default transport: if I use default transport with my custom controls I see the page refresh, but the nothing change. In twentyeleven, default transport is used eg. for color scheme option, but I can’t unserstand how there the preview change according to setting…
Aswer was more easier than it seemed to me…
HAve you notice how they have cleverly diasbaled links back to the admin URL in teh previewr, so you don’t go round in a ‘tunnel’ of links.
But it is counter intuitive, as you view your site in preview / editor level, there are ‘edit page/post’ links onthe page – clicking on the link does not work, of course as it has been disabled, but that is counter intuitive, after all you are modifying your theme and then see some contnet in the previewer you want to change, so I think it would be nice to modify teh edit link in the previewer to save/close the previewer and go to edit page -or just fire up ‘target _blank’.
What do you think? I’m not quite a javascript expert to be able to hack the core customizer code.
I have successfully added a few color pickers to control various theme styles in real-time. Everything works great except when I try to use the customizer to update colors in real-time for hover styles!
Anyone else tried to use the customizer to update color styles?
Note: This works great even for hover styles when the transport is set to refresh, but when transport is set to postMessage it doesn’t work.
Yes, CSS pseudo-selectors like :link, :hover, :visited and so on are not easily accessible using Javascript at all, much less using jQuery. This is because a CSS pseudo-selector isn’t quite the same thing as a selector in jQuery. So the “obvious” approach won’t work.
See, jQuery’s .css() isn’t actually changing the CSS, it’s just modifying the selected elements in the DOM directly by adding inline styles to them, thus causing the change to the viewable portion.
To modify a pseudo-selector, you need to insert or modify a rule in the stylesheet directly from JS. The way you do this actually varies depending on browser (IE is different, basically), and there’s a lot of tricks and caveats to it.
Some examples to help get you started, but honestly, it’s probably easier to just let the refresh happen for those cases.
http://stackoverflow.com/questions/1348741/can-jquery-manipulate-the-global-css-definition-of-the-document
http://stackoverflow.com/questions/311052/setting-css-pseudo-class-rules-from-javascript
http://www.javascriptkit.com/dhtmltutors/externalcss3.shtml
Thanks Otto. After thinking about it I pretty much came to the same conclusion. For hover styles you won’t ever see the change happening in real-time anyway, so what’s the point of jumping through hoops to make it work!
You will only see a change in an elements hover color when you actually hover over it with the mouse. So, simple solution for hover color picker styles is to use the transport refresh method. No one will ever know.. 😉
I also had problems when trying to make real-time changes work with html elements with !important added to the style rule. Most times you can get round this by just making your site CSS better, to get rid of the !important rules. But sometimes this is just outside your control.
For example, with the Twitter widget some of the styles include !important which screws with your attempts to make real-time changes to the Twitter text/link colors via the theme customizer.
Fortunately there is a neat solution here (see second answer): http://stackoverflow.com/questions/1986182/how-to-include-important-in-jquery
I’ve tested it and it works pretty well.
Alternatively, instead of using jQuery, if you *really* need this, you might consider packaging YUI 3 and using the YUI Stylesheet system instead:
http://yuilibrary.com/yui/docs/stylesheet/
I’ve gotten this working well using jQuery hover(): http://api.jquery.com/hover/
Great tip, thanks!
Otto, looks like WP_Customize_Image_Control is not creating the uploaded images tab. Actually, it appears when I upload images without closing the Customizer. However, when closed, the tab is gone. Any thoughts on this?
What version of WordPress, as at 3.4.2 due to a ‘bug’ they did this “Prevents improperly sized images from being uploaded as headers from the customizer.” they did it by simply removing the upload function from the customizer see http://core.trac.wordpress.org/ticket/21355
Still the same issue on 3.5. 🙁
Ok, got it. I have to extend WP_Customize_Image_Control and add my own
function tab_uploaded
to filter my attachments. Seems that all I have to do is create a context for my uploads so then I can useget_posts()
the same way WP uses in WP_Customize_Background_Image_Control.Rather than adding the chunk of JS in our footer for the real-time preview, can a script (a separate file) be enqueued with wp_enqueue_script() on customize_register? Seems to work for me, but I don’t know if I’m messing something else I haven’t found yet.
Hi,
I am getting something strange now on my theme, with twenty-eleven and the way I coded my thme options, if you change the background color, you get a smooth transition. But now I get a complete screen refresh (goes white for a second)when I select an item for change. Any one else experieneced this. I have tried to backtrack my code but can’t find the issue. Any clues would be helpful.
I have a strange issue.
I’ve created a colour selector for a #header { background: # } and linked it up to the one in my theme-options.php
When I use the colour selector in customize and “update and save” the background goes blank (NULL) – if I then go to my theme options page, I can see the colour I just selected in customize in my theme options page.
I then have to “save” on the theme options page for the colour to be added to the header background?
I’m using a dynamic php stylesheet to carry the variables, otherwise there should be no difference from this tutorial
my code for customise is as follows:
Hi,
is there a way to choose which element inside a new section comes first?
I tried to add the ‘priority thing’ to the setting part but… it doesn’t work.
I have 8 different image upload that will be used for a slideshow but it shows up with apparently no sense…
Put the priority values on the controls, not on the settings.
Thank you very much, as expected, now it works 🙂
Is there a way to create sub-section?
I can’t find any documentation about this…
[…] Theme and plugin developers interested in adding new options to a theme’s Theme Customization page should see the documentation on the Theme Customization API. Additional tutorials on the Theme Customization API are available at the Ottopress.com website. […]
Great tutorial. Works great for me. One question I have is what would be the best way to add conditions to the customizer? I know the transport option only works for the preview pane, but could that function be used in the customizer itself? For example, if I choose “layout #1”, then I want a set of options to display for layout #1, or if I choose “layout #2”, I’d want a separate set of options to show up for that layout.
Hey Otto & world… I’m utilizing the theme customizer from within a plugin which extends certain themes. Long story short, I have it working _perfectly._ Perfectly, that is, with one caveat:
The user must have already used the plugin’s regular options panel to save some options (saved as a serialized array). Here’s what’s happening.
If a user visits the Customizer prior to saving anything within the plugin’s distinct panels, then the Customizer only partially works. The options can be edited & even saved in the left panel, but despite the fact that the preview pane refreshes, it isn’t reflecting changes in the options.
Saving the Customizer, and then refreshing the whole thing (or visiting the plugin panel) reveals that the options are in fact saved. Revisiting the Customizer after that, the live preview works fine.
The plugin uses a couple of options, each a serialized array of a bunch of options related to “behind the scenes” features of a few themes. I’m hoping to avoid creating dummy, empty default options if at all possible, just to trick the Customizer into working as expected from the start.
Any ideas on how to get around this?
You can see the exact code I’m using if you want.
Rick,
By chance are you using the wp function get_theme_mods() in your theme to get an array of all the customizer settings? I was, and discovered the customizer preview only works when you use the individual get_theme_mod(‘[some setting]’) to display each individual custom setting. The customizer preview only filters the return value of get_theme_mod() and not get_theme_mods().
Nope. It’s all “get_option” in the plugin. My addition to the customizer doesn’t actually affect anything in the theme itself — it’s modifying plugin options.
And everything works, except on a fresh setup where the options don’t yet exist.
Thanks for this fantastic article! I’m wondering if it is possible to set required resolution and maximum height and width values – OR – to resize the file to the required dimensions and resolution upon upload with WP_Customize_Image_Control. Can you point me in the right direction?
Any luck with this? I’m looking for the exact same thing. If we could just get the image/attachment ID from stuff uploaded via WP_Customize_Image_Control you could run all kinds of neat functions.
Yes John I am wondering the same thing to set resolution. Any answers to this one ?
[…] How to leverage the Theme Customizer in your own themes […]
Thanks for the great article it really helped me out.
But I’m stuck on one thing.
I added a setting which changes the layout of a blogpost with or without a sidebar.
This requires the site to reload for it to change the setting (just like the dark theme in your video) and can’t be done with javascript/post-message.
The site does refresh but it doesn’t update the setting, if I hit save and publish it does update the setting.
Is it possible to see this kind of settings in the live preview?
I’ve added in a ‘select’ type but don’t know how to get the value of it to display on the front end of the site.
// Hours: Monday
$wp_customize->add_setting( 'open_mon', array(
'default' => '09',
));
$wp_customize->add_control( 'open_mon', array(
'label' => 'Monday: Open',
'section' => 'opening_hours',
'type' => 'select',
'choices' => array(
'08' => '08:00AM',
'09' => '09:00AM',
'11' => '10:00AM',
'12' => '11:00AM',
'13' => '12:00PM',
'14' => '1:00PM',
),
));
Also don’t know how to display the value from dropdown-pages type.
im using
$wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, ‘rdr_settings_image’, array(
‘label’ => ‘Profile Pic’,
‘section’ => ‘rdr_settings’,
‘settings’ => ‘rdr_settings_image’,
) ) );
and retrieving it by
get_theme_mod( ‘rdr_settings_image’ );
but i can only get the full-size image, i want the thumb. How can i do that?
[…] Theme and plugin developers interested in adding new options to a theme’s Theme Customization page should see the documentation on the Theme Customization API. Additional tutorials on the Theme Customization API are available at the Ottopress.com website. […]
[…] Theme and plugin developers interested in adding new options to a theme’s Theme Customization page should see the documentation on the Theme Customization API. Additional tutorials on the Theme Customization API are available at the Ottopress.com website. […]
[…] thanks to Otto and his Theme Customizer tutorial, which I referred to more than a few times when getting IceChimp’s Customizer to work […]
[…] thanks to Otto and his Theme Customizer tutorial, which I referred to more than a few times when getting IceChimp’s Customizer to work […]
Image uploads using original image rather then cropped image.
How can i make sure system using cropped version?
Just wondering.. Why can’t we click to a blogpost in the preview, to design (for example) the comment styling? When I click on a link nothing happens..
You can. At least, I can. That frame with the preview is just a view of the live site, with the changes applied. You can click any link on there to see what the next page looks like with the same changes.
Thanks for confirming Otto! It doesn’t work here, so I probably broke something.. Now I know it should work, I’ll start a bug hunt! Thanks 🙂
[…] Theme Customizer Tutorial by Otto […]
Hi Otto, great work.
I have never played with theme options before and this is my first try. I have one little problem that I fully don’t understand, and that’s how do I output the serialized settings.
I have been trying this out, but the settings end up blank 🙁
The code “get_theme_mod(‘roots_theme_options[nav_bg]’);” doesn’t make any sense. Theme mod saved options are already specific to the theme, you don’t need extra array parameters around them.
Without knowing how you’re referencing the options in the first place, I can’t give you an exact answer, but it should be something closer to get_theme_mod(‘nav_bg’). You’re not using serialized settings if you’re using theme mods, or rather, the serialization is hidden from you.
Wow, that was fast.
Reading your answer I do realize I’m a lost cause 🙁
I used your colorpicker code from your example, but couldn’t find a way to output my setting, so I went to the codex and found some snippets of code there, but as I said, i haven’t fully understood the concept of how this works, but that’s ok, then I have some catching up to do.
Thanks again for your answer, it helped more then you think. I’ll post a follow up, when I solved it.
Try looking at the code from my next post in this series instead. This post was meant to help theme authors who already have settings pages in their existing themes to convert to the Customizer. If you’re making a new theme entirely, then this may make more sense:
http://ottopress.com/2012/theme-customizer-part-deux-getting-rid-of-options-pages/
[…] few days after I published this, Otto on WordPress published a tutorial on using the Theme Customizer, which will be released with WordPress 3.4 before the end of the year. It’s great to see the […]