Adding custom controls to your Customization API

In the last post, I talked about what the built in Customization API is and how to use it in your theme. Besides the built in customizer options like input fields, check boxes etc., there are few built in controls that you can use. But what if you want to enhance few of them, or add new ones? Then you’ll have to build your own.

In your customizer.php right before you add the function for setting up your custom control (or at the top of the file), you’ll need to add

require_once 'custom_controls.php';

This will call for the aforementioned file, that is in the same place where our customizer.php is, where we’ll define our custom controls. In the js folder you can place custom_controls.js and in the css folder custom_controls.css . In those files we’ll add any css styling and custom JavaScript that we might need for our controls.

Essentially, we’re adding custom controls in our customizer.php with this kind of code:

$wp_customize->add_control(new MY_NEW_Custom_control($wp_customize, 'control_name',
array( /*labels and additional description goes here*/
)));

But for it to work, we need to extend the built in WP_Customize_Control class with our own. Then when we want to add it, we create a new object out of our control. This way you can reuse this code as many times as you want (yay for object-oriented programming :D).

Let’s get on with our custom controls. If you know all about the ins and outs of custom controls, and just want to see what controls I have so far, just head on to my git repository and download the files. I update it when I find out some new and cool controls.

Custom check box switch

In your custom_controls.php file wrap the whole thing in

if (class_exists('WP_Customize_Control')){}

to avoid any errors if the customizer isn’t present. The first control that we’ll create is the custom check box. Regular check boxes can be a bit dull. Why not add a bit of life to them? The full code is

class Toggle_Checkbox_Custom_control extends WP_Customize_Control{
public $type = 'toogle_checkbox';
public function enqueue(){
wp_enqueue_style( 'custom_controls_css', get_template_directory_uri().'/inc/customizer/css/custom_controls.css');
}
public function render_content(){
?>
<div class="checkbox_switch">
<div class="onoffswitch">
<input type="checkbox" id="<?php echo esc_attr($this->id); ?>" name="<?php echo esc_attr($this->id); ?>" class="onoffswitch-checkbox" value="<?php echo esc_attr( $this->value() ); ?>" <?php $this->link(); checked( $this->value() ); ?>>
<label class="onoffswitch-label" for="<?php echo esc_attr($this->id); ?>"></label>
</div>
<span class="customize-control-title onoffswitch_label"><?php echo esc_html( $this->label ); ?></span>
<p><?php echo wp_kses_post($this->description); ?></p>
</div>
<?php
}
}

So, we’ve created a Toggle_Checkbox_Custom_control . Inside each control we’ll enqueue our .js and .css files (if necessary). In our case we only need css, because we’re making styling changes after all. You’ll need to set up a type, and a method (a function) that will render your new control. In our case we’re added some additional wrappers to our check box. Remember, in the customizer.php we’re adding these controls by creating new objects. So $this will be a reference to that particular object. The usual object oriented approach. Now this is pretty straight forward. On to the css

.customize-control-checkbox label{
margin-left: 0;
padding-top: 0;
padding-bottom: 0;
line-height: 28px;
}

.onoffswitch_label{
display: inline-block;
vertical-align: top;
margin-top: -1px;
width: 200px;
}

.onoffswitch {
position: relative;
width: 40px;
display: inline-block;
float: right;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select: none;
}

.onoffswitch-checkbox {
display: none!important;
}

.onoffswitch-label {
display: block;
overflow: hidden;
cursor: pointer;
height: 18px;
padding: 0;
line-height: 18px;
border: 2px solid #9E9E9E;
border-radius: 18px;
background-color: #9E9E9E;
transition: background-color 0.2s ease-in;
}

.onoffswitch-label:before {
content: "";
display: block;
width: 18px;
margin: 0;
background: #EBEBEB;
position: absolute;
top: 0;
bottom: 0;
right: 20px;
border: 2px solid #9E9E9E;
border-radius: 18px;
transition: all 0.2s ease-in 0s;
}

.onoffswitch-checkbox:checked + .onoffswitch-label {
background-color: #42A5F5;
}

.onoffswitch-checkbox:checked + .onoffswitch-label,
.onoffswitch-checkbox:checked + .onoffswitch-label:before {
border-color: #42A5F5;
}

.onoffswitch-checkbox:checked + .onoffswitch-label:before {
right: 0;
}

I’ve borrowed the css from this freebies page. Now all you need to do is to add the newly created control to your main file.

/**
Custom Checkbox
**/
$wp_customize->add_setting('custom_checkbox', array(
'default' => false,
'sanitize_callback' => 'mytheme_checkbox_sanitization',
));
$wp_customize->add_control(new Toggle_Checkbox_Custom_control($wp_customize, 'custom_checkbox', array(
'label' => esc_html__('Check me', 'mytheme'),
'type' => 'checkbox',
'settings' => 'custom_checkbox',
'section' => 'section_custom_controls',
)));
Custom checkbox control

Our newly styled checkbox. Much better than the regular boring one :D

Custom information control

Next control will be a simple one — information. Say you just want to put a small notice in your section about the next few controls. This control will give you the option to do so.

class Info_Custom_control extends WP_Customize_Control{
public $type = 'info';
public function render_content(){
?>
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<p><?php echo wp_kses_post($this->description); ?></p>
<?php
}
}

This one doesn’t need any css — it’s just text after all. Add your control and voila!

/**
Info
**/
$wp_customize->add_setting('custom_info', array(
'default' => '',
'sanitize_callback' => 'mytheme_text_sanitization',

));
$wp_customize->add_control(new Info_Custom_control($wp_customize, 'custom_info', array(
'label' => esc_html__('A custom notice', 'mytheme'),
'description' => esc_html__('There are times that you just need to say something.', 'mytheme'),
'settings' => 'custom_info',
'section' => 'section_custom_controls',
)));
Custom information control

Custom control when you want to add some kind of notice text

Separator control

Next one is also a simple one — a separator

/* Custom Separator */

class Separator_Custom_control extends WP_Customize_Control{
public $type = 'separator';
public function render_content(){
?>
<p><hr></p>
<?php
}
}
/**
Separator
**/
$wp_customize->add_setting('separator_1', array(
'default' => '',
'sanitize_callback' => 'esc_html',
));
$wp_customize->add_control(new Separator_Custom_control($wp_customize, 'separator_1', array(
'settings' => 'separator_1',
'section' => 'section_custom_controls',
)));
custom separator control

You never know when you’ll need a separator

Multi input field

The next control is a multiple input field. Basically a type of repeater, when you need to add a list or what ever you might need (in the themes I was working on we used this to add new sidebars).

/* Multi Input field */

class Multi_Input_Custom_control extends WP_Customize_Control{
public $type = 'multi_input';
public function enqueue(){
wp_enqueue_script( 'custom_controls', get_template_directory_uri().'/inc/customizer/js/custom_controls.js', array( 'jquery' ),'', true );
wp_enqueue_style( 'custom_controls_css', get_template_directory_uri().'/inc/customizer/css/custom_controls.css');
}
public function render_content(){
?>
<label class="customize_multi_input">
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<p><?php echo wp_kses_post($this->description); ?></p>
<input type="hidden" id="<?php echo esc_attr($this->id); ?>" name="<?php echo esc_attr($this->id); ?>" value="<?php echo esc_attr($this->value()); ?>" class="customize_multi_value_field" data-customize-setting-link="<?php echo esc_attr($this->id); ?>"/>
<div class="customize_multi_fields">
<div class="set">
<input type="text" value="" class="customize_multi_single_field"/>
<a href="#" class="customize_multi_remove_field">X</a>
</div>
</div>
<a href="#" class="button button-primary customize_multi_add_field"><?php esc_attr_e('Add More', 'mytheme') ?></a>
</label>
<?php
}
}

For this control you’ll need some JavaScript

jQuery(document).ready(function($) {
"use strict";

// ************* Multi_Input_Custom_control *********************

function customize_multi_write($element){
var customize_multi_val = '';
$element.find('.customize_multi_fields .customize_multi_single_field').each(function(){
customize_multi_val += $(this).val()+'|';
});
$element.find('.customize_multi_value_field').val(customize_multi_val.slice(0, -1)).change();
}

function customize_multi_add_field(e){
e.preventDefault();
var $control = $(this).parents('.customize_multi_input');
$control.find('.customize_multi_fields').append('<div class="set"><input type="text" value="" class="customize_multi_single_field" /><a href="#" class="customize_multi_remove_field">X</a></div>');
}

function customize_multi_single_field() {
var $control = $(this).parents('.customize_multi_input');
customize_multi_write($control);
}

function customize_multi_remove_field(e){
e.preventDefault();
var $this = $(this);
var $control = $this.parents('.customize_multi_input');
$this.parent().remove();
customize_multi_write($control);
}

$(document).on('click', '.customize_multi_add_field', customize_multi_add_field)
.on('keyup', '.customize_multi_single_field', customize_multi_single_field)
.on('click', '.customize_multi_remove_field', customize_multi_remove_field);

$('.customize_multi_input').each(function(){
var $this = $(this);
var multi_saved_value = $this.find('.customize_multi_value_field').val();
if(multi_saved_value.length>0){
var multi_saved_values = multi_saved_value.split("|");
$this.find('.customize_multi_fields').empty();
$.each(multi_saved_values, function( index, value ) {
$this.find('.customize_multi_fields').append('<div class="set"><input type="text" value="'+value+'" class="customize_multi_single_field" /><a href="#" class="customize_multi_remove_field">X</a></div>');
});
}
});

// ************* Multi_Input_Custom_control END *********************

});

Basically adding, removing and writing to our custom control. In your customizer.php you’ll add

/**
Multiple input field
**/
$wp_customize->add_setting('multi_field', array(
'default' => '',
'transport' => 'postMessage',
'sanitize_callback' => 'mytheme_text_sanitization',
));
$wp_customize->add_control(new Multi_Input_Custom_control($wp_customize, 'multi_field', array(
'label' => esc_html__('Multiple inputs', 'mytheme'),
'description' => esc_html__('Add more and more and more...', 'mytheme'),
'settings' => 'multi_field',
'section' => 'section_custom_controls',
)));
Multiple input control field

Multi input custom control — you can add any kind of text here that can be used in a different ways

Sidebar drop down control

This control comes in handy when you want to define which sidebar will go with certain page/blog layout. In my case I used it when I wanted to separate shop pages sidebar from single product page sidebar, so you can add this control to choose which one you’ll use on certain page.

/* Sidebar Dropdown field */

class Sidebar_Dropdown_Custom_Control extends WP_Customize_Control{
public $type = 'sidebar_dropdown';
public function render_content(){
?>
<label class="customize_dropdown_input">
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<p><?php echo wp_kses_post($this->description); ?></p>
<?php
global $wp_registered_sidebars;
?>
<select id="<?php echo esc_attr($this->id); ?>" name="<?php echo esc_attr($this->id); ?>" data-customize-setting-link="<?php echo esc_attr($this->id); ?>">
<?php
$sidebar_shop = $wp_registered_sidebars;
if(is_array($sidebar_shop) && !empty($sidebar_shop)){
foreach($sidebar_shop as $sidebar){
echo '<option value="'.$sidebar['name'].'" ' . selected( $this->value(), $sidebar['name'], false ) . '>'.$sidebar['name'].'</option>';
}
}
?>
</select>
<br>
</label>
<?php
}
}

And adding the control is

/**
Sidebar dropdown
**/
$wp_customize->add_setting('sidebar_dropdown', array(
'default' => '',
'sanitize_callback' => 'mytheme_text_sanitization',
));
$wp_customize->add_control(new Sidebar_Dropdown_Custom_Control($wp_customize, 'sidebar_dropdown', array(
'label' => esc_html__('Sidebars', 'mytheme'),
'description' => esc_html__('Choose sidebar for the page you specify', 'mytheme'),
'settings' => 'sidebar_dropdown',
'section' => 'section_custom_controls',
)));
Sidebar drop down control

Sidebar drop down control

This is kind of a variation on built in ‘dropdown-pages’ type control, just with sidebars. You could do the same for categories, custom taxonomies etc. Just tweak the code a bit.

Image radio buttons

The last custom control I’ll add is the image radio buttons. Now this one is a bit different, because you’ll need to include the images for your image select. This is basically radio button re-vamped, kinda like what we did with the check box. This control is a good way to give user a ‘preview’ of sorts. Remember how they say that the image is worth a thousand words? Well that’s absolutely true. When the user sees a radio button for, let’s say layout style in a shop, he only has a written descriptions that should be as concise as possible. Layout right or sidebar right is kinda dry. But if he sees a little image with what the layout can look like, he gets the picture (no pun intended :D). So on to our custom control

/* You need to include the images you want to select. Add as many as you want to. In this example there are 3 images, that are supposed to go in 3 columns in one row.*/

class Image_Select_Custom_Control extends WP_Customize_Control{
public $type = 'image_select';
public function enqueue(){
wp_enqueue_style( 'custom_controls_css', get_template_directory_uri().'/inc/customizer/css/custom_controls.css');
}
public function render_content(){
?>
<div class="customize_image_select">
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<p><?php echo wp_kses_post($this->description); ?></p>
<label>
<input type="radio" name="<?php echo esc_attr($this->id); ?>" value="1" data-customize-setting-link="<?php echo esc_attr($this->id); ?>" <?php checked('1', esc_attr($this->value()) );?>/>
<img src="<?php echo get_template_directory_uri().'/images/image_1.png'?>" alt="<?php esc_attr_e('Option 1', 'mytheme'); ?>" title="<?php esc_attr_e('Option 1', 'mytheme'); ?>" />
</label>
<label>
<input type="radio" name="<?php echo esc_attr($this->id); ?>" value="2" data-customize-setting-link="<?php echo esc_attr($this->id); ?>" <?php checked('2', esc_attr($this->value()) );?>/>
<img src="<?php echo get_template_directory_uri().'/images/image_2.png'?>" alt="<?php esc_attr_e('Option 2', 'mytheme'); ?>" title="<?php esc_attr_e('Option 2', 'mytheme'); ?>" />
</label>
<label>
<input type="radio" name="<?php echo esc_attr($this->id); ?>" value="3" data-customize-setting-link="<?php echo esc_attr($this->id); ?>" <?php checked('3', esc_attr($this->value()) );?>/>
<img src="<?php echo get_template_directory_uri().'/images/image_3.png'?>" alt="<?php esc_attr_e('Option 3', 'mytheme'); ?>" title="<?php esc_attr_e('Option 3', 'mytheme'); ?>" />
</label>
</div>
<?php
}
}

Customizer

/**
Image control
**/
$wp_customize->add_setting('image_options', array(
'default' => '2',
'sanitize_callback' => 'mytheme_text_sanitization',
));
$wp_customize->add_control(new Image_Select_Custom_Control($wp_customize, 'image_options', array(
'label' => esc_attr__( 'Layout', 'mytheme' ),
'description' => esc_attr__( 'Choose the layout for your blog', 'mytheme' ),
'settings' => 'image_options',
'section' => 'section_custom_controls',
)));

And of course, the styling

.customize_image_select label{
display: inline-block;
margin-right: 3px;
margin-bottom: 5px;
}

.customize_image_select label:last-of-type{
margin-right: 0;
}

.customize_image_select label input{
display:none;
}

.customize_image_select label input + img{
border-color: #d3dad7;
border-width: 3px;
border-style: solid;
}

.customize_image_select label input:checked + img{
border-color: #0074a2;
border-width: 3px;
border-style: solid;
}

And you have yourself a cool image radio box to choose

Image radio buttons

Image radio buttons. Much better than the old ones.

And this is it so far. There are others interesting controls out there to add, like Google Fonts one — a colleague of mine created this control, so I’ll need to see how to add it myself first before adding that to my git repo. The Google Fonts is a bit tricky, because you need to add the API key for it, so that you can get a list of all the google fonts. But you can really add what ever kind of control that you can think of.

Implementation of these controls is the same as with the other ones — get_theme_mod().

I hope this was an interesting tutorial, if you have a comment or a question, leave it below :)


Originally published at Made by Denis.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.