Here, we focus on understanding the javascript nuts and bolts of the WordPress theme customizer interface.
This will allow us to –
- Extract and change theme customizer settings.
- Extract and change theme customizer controls.
- Call theme customizer functions, such as refreshes and more.
wp.customize
Understanding the WP theme customizer interface centers around understanding the wp.customize javascript object. The three core files related to wp.customize are –
- wp-admin/js/customize-controls.js – Contains special objects related to the theme customizer interface including Setting, ColorControl, PreviewFrame, Previewer, and more.
- wp-includes/js/customize-preview.js – Sets up and creates the theme customizer interface.
- wp-includes/js/customize-base.js – All theme customizer objects from the above two files are built (i.e. extended from) theme base objects. These base-objects are helpful for showing us what common access functions are available for the higher level objects.
Note that the wp.customize object is commonly set to the api variable in these files.
var api = wp.customize;
There are two important classes of objects contained within wp.customize – settings and controls.
Initializing the wp.customize Object
At the start, the wp.customize object is populated with the array of settings, values, nonces, and more, passed over by the PHP portion of the theme customizer. If we look at the source of theme customizer page, we will notice that at the end of the page, the _wpCustomizeSettings variable is set to a large array of values that looks like this –
var _wpCustomizeSettings = {"theme":{"stylesheet":"genesis-skins","active":true},"url":{"preview":"http:\/\/mysite.com\/","parent":"http:\/\/mysite.com\/wp-admin\/","activated":"http:\/\/mysite.com\/wp-admin\/themes.php?activated=true&previewed","ajax":"\/wp-admin\/admin-ajax.php","allowed":["http:\/\/mysite.com\/"],"isCrossDomain":false, ...
This array is set to the settings attribute in the wp.customize object (source here).
api.settings = window._wpCustomizeSettings;
From this array, which contains the settings and control names and attributes, a set of javascript object settings and controls are created.
Settings and Controls
Control objects are stored in wp.customize.control (as a collection of Values) and setting objects are stored in wp.customize itself (as a collection of Values). The Values class has the following useful access functions that we can use to extract setting and control objects from wp.customize.
- instance( id ) – Gets an object from the collection with the specified ‘id’.
- has( id ) – Returns true if collection contains an object with the specified ‘id’ and false otherwise.
- add( id, value ) – Adds an object to the collection with the specified id and value.
- remove( id ) – Removes an object from the collection.
- create( id ) – Creates a new object using the default constructor, and adds it to the collection.
- each( callback, context ) – Iterates over elements within the collection.
With these tools in hand, we can get to a setting object in the theme customizer interface by doing –
var api = wp.customize, mysetting = api.instance('footer_image');
or for a settings array,
var api = wp.customize, mysetting = api.instance('my_theme_options[footer_image]');
NOTE – If we are making javascript calls from the preview frame, then we would want to set api to parent.wp.customize.
The get function gets us the setting value.
console.log(api.instance('my_theme_options[footer_image]').get()); >http://mysite.com/wp-content/uploads/2013/03/Mech-Girl-Footer4.jpg
We can also change theme customizer setting values to whatever we want by using the set function.
api.instance('my_theme_options[footer_image]').set('http://mysite.com/wp-content/uploads/2013/03/Mech-Girl-Header4.jpg')
Similarly we can get and manipulate control objects.
console.log(api.control.instance('footer_image')); >k {params: Object, previewer: k, id: "footer_image", selector: "#customize-control-footer_image", container: v.fn.v.init[1]…}
For example, if I want to manually set a color controller to a particular value, this is what I would do –
function mySetColor(cname, newColor) { var control = api.control.instance(cname); picker = control.container.find('.color-picker-hex'); control.setting.set(newColor); picker.val( control.setting() ); return; }
cname is the controller name and newColor is the new color we want to assign our controller to.
Another really useful object is the previewer (Previewer class). We can use this object to manually refresh our theme preview interface.
api.instance('my_theme_options[footer_image]').previewer.refresh();
AJAX calls
During Ajax calls, customizer settings are passed back in a $_POST request that looks something like this-
Array ( [wp_customize] => on [theme] => genesis-skins [customized] => {\"blogname\":\"Test Blog\",\"blogdescription\":\"Test Blog with WordPress Test Data\", ... } )
The post values can then be retrieved using $wp_customize->post_value($setting).
Thomas says
Hallo ShibaShake,
I have following line in my custimizer.js:
( function( $ ) {
wp.customize( 'headerbackgroundcolor', function( value ) {
value.bind( function( to ) {
Need value of 'headerbackgroundalpha'
} );
} );
.
.
.
In my Theme Customizer I have the option to set an alpha-value of the header-background. Is it possible to read out the current value of the setting of ”headerbackgroundalpha” inside the wp.customize prozedure above?
Thanks a lot
Brian says
I’m wondering if it’s possible to extend the `customize-control.js` methods that are made available by default. I need to hook in there and do some special logic, but it’s wrapped in an immediately invoked function expression
/* globals _wpCustomizeHeader, _wpMediaViewsL10n */
(function( exports, $ ){
// code
})( wp, jQuery );
So I’m not able to extend the prototype from the window object. Any idea if such a thing is possible? There is even mention of overriding this in the .toggle() methods documentation / description: https://github.com/WordPress/WordPress/blob/master/wp-admin/js/customize-controls.js#L110, but I’m not sure if they mean by simply forking the whole JS file, dequeueing the WP version and enqueuing your own or if they mean or something different.
Wouter says
Hi,
I have a question using the customizer in wordpress. I have a jQuery draggable widget (a logo of a website), only draggable when in “customize theme”. I would like to have it’s position; top and left passed to a control in the customizer of WordPress; so that when saved and published; the logo is effectively where I dragged it to… I need the top and left position (which I have) saved in to a textbox in wordpress customizer in other words… Doing a hook of an object and change it’s settings…Is that possible?
Thanks
ShibaShake says
Yes, I did something similar in my Genesis Skins and Shiba Skins child themes. The blog title text is draggable. The code for that should be in shiba-gs-customizer.php or shiba-skins-customizer.php.
Wouter says
ShibaShake : thanks, your code is very clear; I figured it out, and it now works like a charm! Thank you very much 😉
Wouter says
Still one small problem. In your code, you set two settings left and top… Same what I’m trying to achieve. However, as soon as I set one (left) (instance.setting.set); it immediately refreshes the preview; and does not set the top (which is the second instance.setting.set) in my jQuery code… Hope I’m making myself clear, but I need to hold the “automatic” update; how do I do that? I can do a manual one, from the code above, so that will be no problem.
ShibaShake says
I just left the ‘transport’ attribute for those settings at the default (‘refresh’) rather than ‘postMessage’. postMessage binds a listener to the setting, whereas refresh does not.
http://codex.wordpress.org/Class_Reference/WP_Customize_Manager/add_setting
Wouter says
@Sheba : thx again, I’ve done some experimenting, works very well …
gabriel duncan says
i know i’m a little late to the party…
thanks for this tutorial! i have a question. I want to listen for changes to any control value, say a color picker, but also to ALL control values and then bind a function based on the type of control. is there a nice way to use this api to do that? or do i need to go ahead and define each function manually for each control like the docs say?
any help would be greatly appreciated! thanks again!
sharma chelluri says
ShibaShake,
I implemented this for dynamic changing of color pickers based on previous values.
The detail oriented and untouched subject of customizer helped me and saved lot of time. Million Thanks for your help.
Sharma chelluri
wLc says
This was invaluable. I created a custom drag & drop control and was banging my head on the wall trying to figure out how to get the preview window to refresh.
Thanks a million.
Charlotte says
Really nice to see a customizer tutorial that hasn’t been copied from otto – very useful information here that helped me a lot, thanks and much appreciated!
Dennis says
I really appreciated this post. It showed me exactly what I was struggling with in a client’s theme customizer code. I was struggling with how to set the value once I had gathered it through a thickbox popup. I used the information provided in this post to help create my own class based on the Image Control class and documented the process on my blog at: http://hosting.fancyfiber.com/2013/04/04/wordpress-theme-customizer-custom-image-library/
Again, I really appreciate the information you provided here! Helped immensely.