Introduction
The WordPress customizer is a great tool that lets you easily make changes to the theme of a site. One way it's helpful is when we want to use a theme that has multiple color schemes. For instance the UConn Health Clinical theme is a good example. Each clinical site has a different accent color (like aging, or dental). That color is chosen in the customizer from a select box.
In this post, I'll show you how to add a select box that will let you pick a color scheme that can be used across the site.
To do that, we'll use
- the WordPress customizer
- leafo's scssphp
Setup
We need to do three things in order to print styles to the <head>
of our site from the customizer
- Register customizer settings and interfaces.
- Compile CSS from sass files.
- Print the CSS to the head of the theme.
In general we break things out into classes, but for the sake of brevity, I'm going to pretend that all of this happens within the functions.php
file.
Registering Your Customizer
The first thing to do is hook into the customize_register
action. This will allow you to add your own customizer sections, panels, and settings. To do that, the function that you use will take a customizer instance as an argument so that you can use its methods.
<?php
// functions.php
add_action('customize_register', 'register_controls');
function register_controls($wp_customizer) {
// registered controls and settings go here.
}
Next, it's time to create a section within the WordPress customizer that will hold the settings. There are some default settings within the customizer, however it's nice to keep everything within one or more sections devoted specifically to the theme. That way users will know what's part of WordPress and what's part of the theme itself. To do that, we'll use the add_section
method on the $wp_customizer
instance that's passed into the function.
<?php
// functions.php
add_action('customize_register', 'register_controls');
function register_controls($wp_customizer) {
$wp_customizer->add_section('my_section', array(
'title' => __('Customize the Theme', 'my-theme'),
'priority' => 10,
'description' => __('This will go above the default WordPress sections', 'my-theme')
));
}
After registering the section, it's time to register settings and controls. These will allow you to make and save choices about the theme to the database. To do this, we'll use the add_setting
and add_control
methods on the instance. The add_setting
method creates space in the database for the choice. The add_control
method creates the interface for the user. In this case, the control will be a select box with options for the names of the different schemes.
<?php
// functions.php
add_action('customize_register', 'register_controls');
function register_controls($wp_customizer) {
$wp_customizer->add_section('my_section', array(
'title' => __('Customize the Theme', 'my-theme'),
'priority' => 10,
'description' => __('This will go above the default WordPress sections', 'my-theme')
));
// create a setting to save in the database called scheme_choice
// the default for the setting will be blue
$wp_customizer->add_setting('scheme_choice', array(
'default' => 'blue',
'type' => 'theme_mod'
));
// add a select box to the interface with three choices.
$wp_customizer->add_control(new WP_Customize_Control(
$wp_customizer,
'scheme_choice',
array(
'label' => __('Color Scheme', 'my-theme'),
'section' => 'my_section',
'settings' => 'scheme_choice',
'type' => 'select',
'choices' => array(
'blue' => __('Blue', 'my-theme'),
'red' => __('Red', 'my-theme'),
'grey' => __('Grey', 'my-theme')
)
)
);
}
So far so good. Now when a user makes a choice for the color scheme, it will be saved in the database in the wp_options
table as a theme_mod
.
Defining Color Schemes
Because the choice is saved as a theme_mod
, you can retrieve it with the get_theme_mod
function.
This function takes two arguments.
- The name of the setting you want to retrieve
- A default in case retrieval fails
Based on this, you can write a function using a switch/case
statement that will give you a color scheme.
<?php
// still in functions.php if you like...
function get_color_scheme() {
// the theme mod 'scheme_choice' is what we defined above.
$scheme_choice = get_theme_mod('scheme_choice', 'blue');
// define a new array for the scheme.
$color_scheme = array();
switch ($scheme_choice) {
case 'red':
// these can be any valid CSS color (e.g. hex, rgb, etc...)
$color_scheme['primary'] = 'red';
$color_scheme['secondary'] = 'orange';
// define other colors...
break;
case 'grey':
$color_scheme['primary'] = 'grey';
$color_scheme['secondary'] = 'yellow';
break;
default:
// blue is the default selection...
$color_scheme['primary'] = 'blue';
$color_scheme['scheme'] = 'purple';
break;
}
// return the color scheme
return $color_scheme;
}
The next thing to do is create a separate directory for sass files to be used by the customizer. In that directory, create a variables.scss
file which will be imported into your main sass file. The variable names will be the same as those you define in the array that's returned from the previous function.
/* @import variables.scss into the main customizer scss file. */
$primary = 'red' !default;
$secondary = 'orange' !default;
These sass variables are now available throughout your customizer sass application. The !default
statements are there only as a safeguard. They'll be overwritten by your choices in the next step.
Compiling CSS
Next it's time to turn the sass files into css which can be used in the theme. To do that, you'll need to
require
leafo's scssphp library in your functions.php file. There are several ways to do this depending on how you manage PHP libraries. That's a little outside the scope of this tutorial, but worst comes to worst, you can download it and place the appropriate directories in your project.- hook into the
customize_save_after
WordPress action - set an import path for leafo
- call the
get_color_settings
function to get the color scheme - set a formatter for leafo. This will define how the CSS appears once printed to the page. I like the compressed formatter for this.
- compile the CSS
- save the css to the database as an option.
Kind of a lot! But that's ok. Each step builds on the last.
<?php
// still in functions.php
// this assumes you're using composer to require leafo
require_once get_stylesheet_dir() . '/vendor/leafo/scssphp/scss.inc.php';
// use the leafo compiler directly
use LeafoScssPhpCompiler;
// run a function when the customizer saves.
add_action('customize_save_after', 'compile_css');
function compile_css($customizer) {
// the directory where the sass files just for the customizer are
$path = get_stylesheet_dir() . '/customizer_sass';
// the color scheme returned by the function defined above.
$color_settings = get_color_settings();
// create a new Compiler with options
$scss = new Compiler();
$scss->setVariables($color_settings);
$scss->setImportPaths($path);
$scss->setFormatter('LeafoScssPhpFormatterCompressed');
// compile the sass files
/*
Leafo will compile any valid string in the compile
method as if it were sass. In this case, it's importing the
app.scss file which in turn imports any other files.
*/
$compiled = $scss->compile('@import "app.scss";');
// create a new option in the db if it doesn't exist
if (!get_option('customizer_sass')) {
add_option('customizer_sass');
}
// store the compiled css in the db.
update_option('customizer_sass', $compiled);
}
Printing the CSS
Now that the CSS is stored in the database, the last thing to do is print it to the page so that it does something. In general, it's useful to have these styles come after all the other theme and plugin styles. To ensure that happens, you can print them directly inside a style tag. The hook to use to do this is wp_head
. So to finish the application, you need to
- hook into
wp_head
- retrieve the
customizer_css
option data you saved above. echo
the CSS onto the page
<?php
// you guessed it. this is still functions.php
add_action('wp_head', 'print_css');
function print_css() {
$customizer_css = get_option('customizer_css');
echo "<style id='customizer_css'>$customizer_css</style>";
}
Wait! We're not quite done...
Yeah... sorry. You might think that was it right? But there's one more thing I like to add.
Imagine - let's say you change your secondary color for the red theme from orange to pink. It looks amazing! But right now, if someone wants to make that change, they need to:
- select a new color scheme in the customizer
- publish the change
- go back to their "real" choice
- publish again
This is kind of a hassle if you have more than one site. Even with only one site it's kind of ridiculous. Wouldn't it be better if you just had a button that would let handle all that for you? Of course it would!
So, let's go back to where we register the customizer controls and add one. Then we'll make sure it re-compiles the css.
This code will create an input button which will submit a GET request with the name 'color-scheme-refresh'.
<?php
// functions.php
function register_controls($wp_customize) {
// all the other sections, settings, controls.
// our new button.
$wp_customize->add_control('color_scheme_refresh', array(
'label' => __('Refresh the color scheme', 'my-theme'),
'type' => 'submit',
'settings' => array(),
'section' => 'my-section',
'input_attrs' => array(
'value' => __('Refresh theme', 'my-theme'),
'class' => 'button button-primary',
'name' => 'color-scheme-refresh'
)
));
}
Now we need to watch for $_GET
to have the color-scheme-refresh
property and then re-run the function to compile the css.
<?php
if (isset($_GET['color-scheme-refresh'])) {
do_action('customize_save_after', 'compile_css');
}
Conclusion
Hooray!
You did it!
Now you can add customizer options for styles and update theme (relatively) painlessly. I think the important thing here is to keep the functions' behavior separate. For instance, with one function to register/display customizer controls and another to keep track of the color schemes, you can maintain the application more easily.
Working with the WordPress customizer is a great introduction to many of the more abstruse aspects of WordPress development. The first time I tried to make an application like this, it took a really long time. There were database interactions, component display interactions, a variety of hooks and functions, etc...
Hopefully this brief guide will help you build your own customizer applications.