What is the theme customization API?
The WordPress theme customization API allows you to easily create custom theme configuration options that can be changed through the WordPress admin panel. It refers to the configuration options that can be found under the Appearance > Customize page in the menu. This page is convenient and easy-to-use, both from the users’ and developers’ viewpoint. Developers can use pre-existing classes and functions to quickly make the theme more customizable, while users can have a single customization page with all the theme options that can be live previewed before saving them.
Creating custom configuration fields
The first step when working with the theme configuration API is to create a function that will be hooked to customize_register action. To do that, create a new file (called e.g. theme-settings.php) in your theme’s root directory and add the following code:
<?php
function mys_customize_register($wp_customize)
{
}
add_action('customize_register', 'mys_customize_register');
$wp_customize is an instance of WP_Customize_Manager class, that contains built-in methods that handle the creation of custom settings and corresponding form fields. These methods are add_setting(), add_section() and add_control().
The Add_Setting() function is used to add a new theme setting. In this example, you will add four custom settings:
function mys_customize_register($wp_customize)
{
$wp_customize->add_setting('header_title');
$wp_customize->add_setting('header_subtitle');
$wp_customize->add_setting('intro_text');
$wp_customize->add_setting('featured_post');
}
Each setting can have additional options, such as the default value, access control and input sanitization:
function mys_customize_register($wp_customize)
{
$wp_customize->add_setting('header_title', array(
'default' => 'Lorem ipsum',
'capability' => 'edit_theme_options',
'sanitize_callback' => 'sanitize_header_title'
));
$wp_customize->add_setting('header_subtitle');
$wp_customize->add_setting('intro_text');
$wp_customize->add_setting('featured_post');
}
add_action('customize_register', 'mys_customize_register');
function sanitize_header_title($title) {
return ucfirst($title);
}
All settings must belong to a certain section. A section is a group of settings that is added using the add_section() function:
$wp_customize->add_section('mys_general_section', [
'title' => 'General settings',
'priority' => 1
]);
There are a few predefined sections to which the settings can be added. These are:
- title_tagline – Site Title & Tagline
- colors – Colors
- header_image – Header Image
- background_image – Background Image
- nav – Navigation
- static_front_page – Static Front Page
However, the settings will still not appear on the theme customizer page. You have to create a control (i.e. form field element) for each setting and assign it to a desired section using add_control() function:
$wp_customize->add_control('mys_header_title_ctrl', [
'label' => 'Header Title',
'section' => 'mys_general_section',
'settings' => 'header_title',
'type' => 'text'
]);
For the setting from above, form field type is set to text. However, other types are also available:
- text
- checkbox
- radio
- select
- textarea
- dropdown-pages
- email
- URL
- number
- hidden
- date
Some of these types accept additional configuration arguments. For example, if form field type is selected, then you need to specify which options will appear in the dropdown:
$pages = get_posts([
'nopaging' => true,
'post_type' => 'page',
'post_status' => 'publish'
]);
$page_ids = array_map(function($el) {
return $el->ID;
}, $pages);
$page_names = array_map(function ($el) {
return $el->post_title;
}, $pages);
$wp_customize->add_control('mys_featured_post_ctrl', [
'label' => 'Featured Post',
'section' => 'mys_general_section',
'settings' => 'featured_post',
'type' => 'select',
'choices' => array('' => '') + array_combine($page_ids, $page_names)
]);
Finally, don’t forget to include the theme settings file in functions.php:
require_once __DIR__ . '/theme-settings.php';
You can now show the values of these settings anywhere in the theme:
echo get_theme_mod('header_title');
Wrapping it up
Full code of the theme customization function would look like this:
function mys_customize_register($wp_customize)
{
$wp_customize->add_setting('header_title', array(
'default' => 'Lorem ipsum',
'capability' => 'edit_theme_options',
'sanitize_callback' => 'sanitize_header_title'
));
$wp_customize->add_setting('header_subtitle');
$wp_customize->add_setting('intro_text');
$wp_customize->add_setting('featured_post');
$wp_customize->add_section('mys_general_section', [
'title' => 'General settings',
'priority' => 1
]);
$wp_customize->add_control('mys_header_title_ctrl', [
'label' => 'Header Title',
'section' => 'mys_general_section',
'settings' => 'header_title',
'type' => 'text'
]);
$wp_customize->add_control('mys_header_subtitle_ctrl', [
'label' => 'Header Subtitle',
'section' => 'mys_general_section',
'settings' => 'header_subtitle',
'type' => 'text'
]);
$wp_customize->add_control('mys_intro_text_ctrl', [
'label' => 'Intro Text',
'section' => 'mys_general_section',
'settings' => 'intro_text',
'type' => 'textarea'
]);
$pages = get_posts([
'nopaging' => true,
'post_type' => 'page',
'post_status' => 'publish'
]);
$page_ids = array_map(function($el) {
return $el->ID;
}, $pages);
$page_names = array_map(function ($el) {
return $el->post_title;
}, $pages);
$wp_customize->add_control('mys_featured_post_ctrl', [
'label' => 'Featured Post',
'section' => 'mys_general_section',
'settings' => 'featured_post',
'type' => 'select',
'choices' => array('' => '') + array_combine($page_ids, $page_names)
]);
}
add_action('customize_register', 'mys_customize_register');
function sanitize_header_title($title) {
return ucfirst($title);
}