WordPress customizer isn’t a new thing. It was introduced back in WP 3.4 version, and has come a long way since then. While there are many alternative frameworks out there, that will give you an ‘options framework’, it’s the only one officially supported by WordPress (not only officially supported but mandated by the review team from the WordPress.org).
Notice: This article was written in 2016. WordPress has changed a lot since then, so take this article with a grain of salt…
In this tutorial I’ll explain how to implement the customizer, set the panels, sections and how to dynamically change things like colors of your theme elements dynamically from the customizer. In other posts, I’ll explain how to add custom controls and enhance your theme.
There is one thing that I’ll have to add about the customizer. No matter how great it is to have option panel whose changes you can see immediately, there are some drawbacks to it (that should be fixed in the upcoming release of WP – 4.5 version). If you pack your customizer full of options and controls, your customizer screen will become painfully slow. But the team at make.wordpress.org is really doing a great job, and from what I’ve read they have added some new and exciting things that will be released with the 4.5 release of WordPress. It’s constantly changing, and being improved, so I still think that it’s a great thing to have in your theme.
Adding the customizer
When you install your WordPress on the server, the customizer options will be included in it. Which is a great thing, as you don’t need any additional installations or plugins. I’m basing this on twentysixteen theme, so I’ll assume its folder structure, but you’re free to add the files in what ever folder you want, just be sure to point to the correct folder when requiring your files. Moreover twentysixteen already has a customizer file so you can either see how they did it, or just follow my tutorial.
In your functions.php file, add the main customizer file in it’s own folder:
/********* Theme Customizer Options ***********/
require_once( get_template_directory() . '/inc/customizer/customizer.php' );
Code language: PHP (php)
Now you need to create customizer folder and add customizer.php in it. I’m doing it like this, because later on I’ll add custom controls file in it and separate css and js files as well.
In the file you’ll want to add your function to the customize_register hook
add_action( 'customize_register', 'mytheme_customize_register' );
if (!function_exists('mytheme_customize_register')) {
function mytheme_customize_register( $wp_customize ) {
//Your settings will go here
}
}
Code language: PHP (php)
All your custom settings will go inside this function. The $wp_customize object is passed automatically to the function, and we will preform all customizations through methods of the $wp_customize object. All there is to do now is to add our panels, sections and settings.
Panels hold one or more sections, and sections hold one or more options. You can, if you want to, just add sections and options (if you don’t have many settings in your theme). Let’s say that I want to add a logo to my header. I’ll add a ‘Header’ section, and in it I’ll add a ‘header_logo’ option like this:
/**
------------------------------------------------------------
SECTION: Header
------------------------------------------------------------
**/
$wp_customize->add_section( 'section_header', array(
'title' => esc_html__( 'Header', 'mytheme' ),
'priority' => 10,
));
/**
Header Logo
**/
$wp_customize->add_setting( 'header_logo', array(
'default' => '',
'sanitize_callback' => 'esc_url_raw',
));
$wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'header_logo', array(
'label' => esc_html__( 'Header Logo', 'mytheme' ),
'settings' => 'header_logo',
'section' => 'section_header',
)));
Code language: PHP (php)
The code itself is pretty straightforward. You are adding sections with
$wp_customize->add_section( string $section_name, array $options_array);
and options (settings) with
$wp_customize->add_setting( string $settings_name, array $settings_options_array);
to which you add your control. Control can be a simple one like text, checkbox, dropdown pages or a bit more complex one like image upload, or a custom control. Say we want to add an input field where we’ll put a text next to the header all in the same section. We’d add
/**
Logo Text
**/
$wp_customize->add_setting( 'logo_text', array(
'default' => esc_html__( 'I\'m cool!', 'mytheme' ),
'sanitize_callback' => 'mytheme_text_sanitization',
));
$wp_customize->add_control( 'logo_text', array(
'label' => esc_html__( 'Logo Text', 'mytheme' ),
'description' => esc_html__( 'A piece of text that will be shown next to the header logo.', 'mytheme' ),
'type' => 'text',
'section' => 'section_header',
));
Code language: PHP (php)
This will give us two settings like on the image below
Easy as that. Now in the case of image upload, we used a provided class WP_Customize_Image_Control , while in the case of a simple text field, we just specified the name of the control, and in the options array we added what this control is: label, description, type and in what section it should go.
Adding a panel, wouldn’t be too hard as well
$wp_customize->add_panel( 'header_panel', array(
'title' => esc_html__( 'Header Panel', 'mytheme' ),
'priority' => 10,
) );
Code language: PHP (php)
and you’d add to your section settings
$wp_customize->add_section( 'section_header', array(
'title' => esc_html__( 'Header', 'mytheme' ),
'priority' => 10,
'panel' => 'header_panel',
));
Code language: PHP (php)
One thing that you might have noticed is the sanitize_callback key in the array for our setting. This is an optional setting that will call the function name which will then sanitize the input value of your setting. You can create your own sanitization functions, like for instance
/********* Sanitization Functions ***********/
if (!function_exists( 'mytheme_allowed_tags' ) ) {
function mytheme_allowed_tags() {
return array(
'a' => array(
'href' => array(),
'title' => array()
),
'br' => array(),
'em' => array(),
'strong' => array(),
'i' => array(
'class' => array()
),
'cite' => array(
'title' => array()
),
);
}
}
if(!function_exists( 'mytheme_text_sanitization' ) ) {
function mytheme_text_sanitization( $input ) {
return wp_kses_post( force_balance_tags( $input ) );
}
}
if(!function_exists( 'mytheme_checkbox_sanitization' ) ) {
function mytheme_checkbox_sanitization( $input ) {
if ( $input == 1 ) {
return 1;
} else {
return '';
}
}
}
if(!function_exists( 'mytheme_sanitize_integer' ) ) {
function mytheme_sanitize_integer( $input ) {
if( is_numeric( $input ) ) {
return intval( $input );
}
}
}
Code language: PHP (php)
or use ones provided by WordPress. Themeforest review team requires that every settings has a sanitization callback – security is important after all.
This gives you some idea how to add your own settings. But what if I want to change the color of the anchors on my page? WordPress got you covered :)
/**
Anchor Color
**/
$wp_customize->add_setting('anchor_color', array(
'default' => '#ff503f',
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color',
));
$wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'anchor_color', array(
'label' => esc_attr__('Anchor Color', 'mytheme'),
'settings' => 'anchor_color',
'section' => 'section_header',
)));
Code language: PHP (php)
Ok, that’s great, but how do you actually use it?
Well for our header, we’d obviously need to find where our header is located – header.php sounds like a good place to start. To fetch our newly created settings, we’re going to use get_theme_mod function. In my twentysixteen it would look something like:
<header id="masthead" class="site-header" role="banner">
<div class="site-header-main">
<?php
$header_logo = get_theme_mod('header_logo', '');
$header_text = get_theme_mod('logo_text', '');
if(isset($header_logo) && $header_logo != ''): ?>
<a class="logo" href="<?php echo esc_url(get_home_url()); ?>"><img src="<?php echo $header_logo; ?>" alt="<?php esc_html_e('Header Logo', 'mytheme') ?>"></a>
<?php if(isset($header_text) && $header_text != ''): ?>
<div class="logo_text">
<?php echo $header_text; ?>
</div>
<?php endif; ?>
<?php else: ?>
<div class="site-branding">
<?php if ( is_front_page() && is_home() ) : ?>
<h1 class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
<?php else : ?>
<p class="site-title"><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></p>
<?php endif;
$description = get_bloginfo( 'description', 'display' );
if ( $description || is_customize_preview() ) : ?>
<p class="site-description"><?php echo $description; ?></p>
<?php endif; ?>
</div><!-- .site-branding -->
<?php endif; ?>
Code language: HTML, XML (xml)
It’s always good to check if the settings is set and not empty before outputting any HTML.
Now the color settings requires some javascript magic. First notice that we’ve set ‘transport’ => ‘postMessage’ in our color settings. This is an option that can be added to any dynamically changing element on your page. Usually once you’ve changed something in the customizer, your page will refresh. This settings will disable this refresh, and instead you’ll be able to change text or color instantly without any refresh. You can read more about it here.
First we’ll enqueue our javascript by adding an action below our ‘mytheme_customizer_register’ function
add_action( 'customize_preview_init', 'mytheme_customizer_live_preview' );
if (!function_exists('mytheme_customizer_live_preview')) {
function mytheme_customizer_live_preview(){
wp_enqueue_script( 'mytheme-customizer', get_template_directory_uri().'/inc/customizer/js/customizer.js', array( 'jquery', 'customize-preview' ), '', true);
}
}
Code language: PHP (php)
The contents of this file will look like
(function($){
wp.customize('anchor_color', function(value){
value.bind(function(newval){
$('a').css('color', newval);
});
});
wp.customize('blogname', function(value){
value.bind(function(newval){
$('.site-title').html(newval);
});
});
wp.customize('blogdescription', function(value){
value.bind(function(newval){
$('.site-description').html(newval);
});
});
})(jQuery);
Code language: JavaScript (javascript)
The last two additions are blog name (site title) and blog description. For them to work you need to add in your customizer.php file inside your ‘mytheme_customize_register’ function
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
Code language: PHP (php)
And you’re all set. The full customizer.php code is
<?php
add_action( 'customize_register', 'mytheme_customize_register' );
if (!function_exists('mytheme_customize_register')) {
function mytheme_customize_register( $wp_customize ) {
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
/**
------------------------------------------------------------
PANEL: Header
------------------------------------------------------------
**/
$wp_customize->add_panel( 'header_panel', array(
'title' => esc_html__( 'Header Panel', 'mytheme' ),
'priority' => 10,
) );
/**
------------------------------------------------------------
SECTION: Header
------------------------------------------------------------
**/
$wp_customize->add_section( 'section_header', array(
'title' => esc_html__( 'Header', 'mytheme' ),
'priority' => 10,
'panel' => 'header_panel',
));
/**
Header Logo
**/
$wp_customize->add_setting( 'header_logo', array(
'default' => '',
'sanitize_callback' => 'esc_url_raw',
));
$wp_customize->add_control(new WP_Customize_Image_Control($wp_customize, 'header_logo', array(
'label' => esc_html__( 'Header Logo', 'mytheme' ),
'settings' => 'header_logo',
'section' => 'section_header',
)));
/**
Logo Text
**/
$wp_customize->add_setting( 'logo_text', array(
'default' => esc_html__( 'I\'m cool!', 'mytheme' ),
'sanitize_callback' => 'mytheme_text_sanitization',
));
$wp_customize->add_control( 'logo_text', array(
'label' => esc_html__( 'Logo Text', 'mytheme' ),
'description' => esc_html__( 'A piece of text that will be shown next to the header logo.', 'mytheme' ),
'type' => 'text',
'section' => 'section_header',
));
/**
Anchor Color
**/
$wp_customize->add_setting('anchor_color', array(
'default' => '#ff503f',
'transport' => 'postMessage',
'sanitize_callback' => 'sanitize_hex_color',
));
$wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'anchor_color', array(
'label' => esc_attr__('Anchor Color', 'mytheme'),
'settings' => 'anchor_color',
'section' => 'section_header',
)));
}
}
add_action( 'customize_preview_init', 'mytheme_customizer_live_preview' );
if (!function_exists('mytheme_customizer_live_preview')) {
function mytheme_customizer_live_preview(){
wp_enqueue_script( 'mytheme-customizer', get_template_directory_uri().'/inc/customizer/js/customizer.js', array( 'jquery', 'customize-preview' ), '', true);
}
}
Code language: PHP (php)
I hope this tutorial helped you with understanding how customizer works, and how to use it. In the following post I’ll add some custom controls and custom styling to your custom controls like image select, custom checkbox, main color control and some others. If you have any questions feel free to comment below.
Leave a Reply