After the basics were in place, I started adding to Amalgamation (this site’s theme) to make it customizable for someone who might want, say, different pages featured in the front page’s panels. The correct place to put appearance-affecting settings is now the Customizer, which meant a lot of new learning.
It was not without its swearingdifficulties, and for a while I had a nice little hack in place (labeled as such) but I got a handle on it and thought I’d write a bit about the parts that took me while to figure out or were difficult to find information on. This isn’t intended as a self-contained tutorial; I’ll follow this post up with a post of resources. Edit 3/12: The Customizer resource post is up now.
Customizer PHP
In Amalgamation, this is all in customizer.php.
Underscores is a good start on the Customizer, especially for mimicking JavaScript syntax, but begins quite light on the PHP side. All it does is implement partial refresh for a few of the built-in settings. I wanted to add a bunch of new settings and also remove the irrelevant defaults, which you can see near the beginning of amalgamation_customize_register()
.
There were two things I remember giving me pause when adding settings (see code on Pastebin):
The first was keeping the pieces straight, including what needed the same name. The setup is a little convoluted; sections and controls are UI entities – they are about what appears and how in the Customizer pane. Settings are data entities – they hold the values you use controls within sections to select. That’s why they don’t exist within sections like controls do, and why the label and description are set within the control definition. They are, however, tightly coupled to controls, which is why they both get the same label as their first parameter.
The other mild slowdown was not knowing how to define a radio button selection, but hopefully my example makes it clear: in the choices array it is ‘setting’s value’ => ‘value’s description’.
WordPress has a page dropdown included, but I wanted to allow posts as well so I needed a custom control. I began by using a post select dropdown from Paul Underwood, but changing the selection didn’t alert the Customizer that a change had been made – the Save button remained grayed out. Since I didn’t need the flexibility of that control I switched to one by Tom Rhodes that has since disappeared from his GitHub. That one worked, and I’ve since determined that the key was in the select
element having the attribute data-customize-setting-link="<?php echo $this->id; ?>"
. When I added that attribute to Paulund’s code, it worked as desired.
Note that the definition of the custom control needs to be accessible from within the function that’s adding the custom control. The easiest way to do that is to define it within the function, whether directly or via an include statement.
Using the settings in your theme is easy: get_theme_mod( 'setting_name' );
returns (rather than echoes) the value.
Customizer JavaScript
This is in two files in Amalgamation: customizer.js and customizer-controls.js; the enqueuings are in customizer.php.
JavaScript is currently optional for the Customizer but developers are encouraged to use it for essentially all the functionality. I did not (though I intend to at least try it out in the future) but I made good use of JavaScript for dynamic display of controls in the sidebar and for partial refresh in the preview so a small change did not require the whole thing to reload.
The first thing to note is that there are two different actions to hook your script enqueue functions into, depending on whether the script affects the sidebar or the preview pane. The preview is in an iframe so it is effectively a completely separate website; scripts that live in one location can’t affect elements in the other.
For dynamic controls, the enqueue command is this (view on Pastebin):
You can code these as you would any other show/hide commands, but I found I needed to enclose them in an extra $(function(){});
to delay execution and prevent them being overridden. The necessary ids for your elements will be generated following a standard pattern and are easy to find in the web inspector.
For preview AJAX, the enqueue command is this (view on Pastebin):
Note that I’m localizing the script also, as in my previous post about AJAX in WordPress. This of course is only necessary if you actually plan to make AJAX calls. Within the script you have to follow the pattern
wp.customize( 'setting_name', function (value) { value.bind(function (to) { // your css/html change or ajax call }); });
If you leave out value.bind it won’t work. From what I understand, “value” here is the fact of the change, and “to” is the result or contents of the change (e.g. the color code, text of the byline, or id of the page you selected from the dropdown). Once you’re inside you can do whatever you want; it’s no different from JavaScript written from scratch to enact a change on the page. In particular AJAX works the same way as in WP at large.
There’s my contribution for now. Stay tuned for the resource post. Edit 3/21: My selection of customizer resources is posted now.
Marionette photo by Jürgen Howaldt (Own work (selbst erstelltes Foto)) [CC BY-SA 3.0 de], via Wikimedia Commons.