New WP_Customize API – how does it work under the hood?

I noticed that if you make changes trough the new “customize” feature, when you navigate on a different page within the iframe preview document, your changes still apply, even if they are unsaved.

It looks like WP is storing the temporary changes somewhere, and it applies them on the site if the site is viewed in “customize” mode.

But how does the site know it’s in customize mode? Because I don’t see any query arguments appended to the links or anything like that.

Solutions Collecting From Web of "New WP_Customize API – how does it work under the hood?"

There’s a few bits here that apply, but the short of it is this code in customize-preview.js:

this.body.on( 'click.preview', 'a', function( event ) {
    self.send( 'scroll', 0 );
    self.send( 'url', $(this).prop('href') );

The event.preventDefault prevents the links from actually working. The following code then sends a message back upwards telling it to a) scroll back to the top of the page and b) change the URL.

The reason for the messaging here is because there’s not just one iframe, there’s two. The page you clicked to is actually loaded inside another iframe with the settings from the customizer added to it (via a POST indeed), then a fade effect is used to fade out the old one and fade in the new one seamlessly. This prevents the screen going white and ugly and blinking when it switches to the new page.

Also eliminates the need to do filtering and such on the theme code and potentially modify the look of the page. The theme is thus displayed as is, without significant changes to the content of it.

Similar code exists there to prevent form submission from working at all (it just does nothing) and so forth.

The filter for intercepting and handling the customizer values is in class-wp-customize-setting.php. The preview() function adds the filters needed to handle the incoming values, the _preview_filter() function is that filter. It simply takes the get_option() or get_theme_mod() calls, notices when they’re supposed to be modified options, and returns the modified values instead.

You’ll notice that when you click a link in the customizer preview window, the request that is generated is a POST request, instead of a normal GET. The customizer appears to be overriding any link clicks and doing the POST instead, with the following form data:

wp_customize: on
theme: themename
customized: {json-encoded-options-here}
customize_messenger_channel: preview-1

The customized field is what contains the options you’ve modified, so that is where the data is being passed through to your theme. The customizer code then intercepts (through a filter, I’m not sure which one exactly) your theme’s options when they are requested, and replaces them with the values in the customized parameter.