Adding Different Controls to The Customizer in WordPress

Controls are user interfaces used to manage theme settings.

You can add controls to the theme customizer screen using the WordPress customizer API.

You will use an action hook customize_register to add the controls. The hook customize_register takes a callback function. The code for adding the controls is written within this function.

function tornadu_customize_register() {
    // code for adding controls
}
add_action( 'customize_register', 'tornadu_customize_register' );

The code above goes to the functions.php file of your theme, or anywhere that functions.php can access it.

A control needs to be associated with a theme setting. It also needs to have a section and a panel ( if required ).

A control without a setting and a section will not show up in the customizer window.

In a new custom theme, WordPress automatically generates a few default controls. These controls are housed under a few default sections.

Site Identity, Homepage Settings, Additional CSS are the sections created by default in any new theme.

You can add more sections to the theme using add_theme_support function. These sections then groups and displays some controls for some theme settings.

The table below shows the commonly created sections with add_theme_support

add_theme_support(‘custom-logo’)Adds a Logo feature inside Site Identity in customizer
add_theme_support(‘menus’)Adds Menus section in customizer
add_theme_support(‘custom-header’)Adds a Header Image section in customizer
add_theme_support( ‘background_image‘ )Adds Colors and Background Image sections to the customizer

But what about custom controls? If you want to add a new theme setting that is unique to the theme then how to do it?

WordPress core supports several control types that can be associated with theme settings.

Types of controls

  • text
  • textarea
  • checkbox
  • select
  • dropdown-pages
  • radio

The list above shows the common control types you can create in WordPress. You can also create custom controls if you need, but more on that later.

The syntax

The syntax for all the controls is nearly same. See the following generic code –

// call for creating a control - Required
$wp_customize->add_control( 'setting_id'
    array(
        'label'    => '', // arbitrary string
        'description' => '', // arbitrary string
        'section'  => 'section_id', // required
	'type'     => '' // required
    )
);

The code above is for a control where a few parameters are left blank. In general it represents the structure of the code for a control.

It takes a few optional and a few required arguments.

The parameters label and description can take any arbitrary string. Usually descriptive values are used here.

The setting_id, section and type are required arguments.

The setting_id is the id of the theme setting that the control manages and represents. The section parameter needs the section_id that this control is a part of.

The type parameter determines what type of control it is. Based on the type, let us see the controls we can create –

Text Control
$wp_customize->add_control( 'setting_id'
    array(
        'label'    => 'My awesome text label', // arbitrary string
        'description' => 'My awesome text description', // arbitrary string
        'section'  => 'section_id', // required
	'type'     => 'text' // required
    )
);
Select Control
$wp_customize->add_control( 'setting_id'
    array(
        'label'    => 'My awesome text label', // arbitrary string
        'description' => 'My awesome text description', // arbitrary string
        'section'  => 'section_id', // required
	'type'     => 'select', // required
        'choices' => array( // required
            'value1' => __( 'Value 1' ),
            'value2' => __( 'Value 2' ),
            'value3' => __( 'Value 3' ),
            'value4' -> __( 'Value 4' )
         ), 
    )
);
Checkbox Control
$wp_customize->add_control( 'setting_id'
    array(
        'label'    => 'My awesome text label', // arbitrary string
        'description' => 'My awesome text description', // arbitrary string
        'section'  => 'section_id', // required
	'type'     => 'checkbox', // required
    )
);
Textarea Control
$wp_customize->add_control( 'setting_id'
    array(
        'label'    => 'My awesome text label', // arbitrary string
        'description' => 'My awesome text description', // arbitrary string
        'section'  => 'section_id', // required
	'type'     => 'textarea', // required
    )
);
Dropdown Pages Control
$wp_customize->add_control( 'setting_id'
    array(
        'label'    => 'My awesome text label', // arbitrary string
        'description' => 'My awesome text description', // arbitrary string
        'section'  => 'section_id', // required
	'type'     => 'dropdown-pages', // required
    )
);
Radio Control
$wp_customize->add_control( 'setting_id', 
    array(
         'type' => 'radio', // required
         'section' => 'section_id', // required
         'label' => __( 'My awesome radio control' ),
         'description' => __( 'My awesome radio description' ),
         'choices' => array( // required - an array
             'red' => __( 'Red' ),
             'blue' => __( 'Blue' ),
             'green' => __( 'Green' ),
          ),
    ) 
);
Image Control

Image control is used for uploading images for a theme setting. The WP_Customize_Image_Control class is used to create the image control.

$wp_customize->add_control(
       new WP_Customize_Image_Control(
           $wp_customize,
           'setting_id',
           array(
               'label'      => __( 'My Awesome image', 'text-domain' ),
               'section'    => 'section_id',
               'settings'   => 'setting_id',
               'context'    => 'setting context'
           )
       )
 );

Color control

Color control is used to set a color for anything in the theme. It uses the WP_Customize_Color_Control class.

$wp_customize->add_control( 
    new WP_Customize_Color_Control( 
    $wp_customize, 
    'setting_id', 
     array(
        'label'      => __( 'My awsome color control', 'text-domain' ),
        'section'    => 'section_id',
        'settings'   => 'setting_id',
     ) 
   ) 
);

As stated earlier, a control parameter is not standalone. It needs a setting and a section to be associated with. A panel code also needs to be added if the control is a part of a new panel.

Keeping that in mind, the code for a control looks like this –

function tornadu_customize_register($wp_customize) {
    // call for creating a panel - Optional
    // call for creating a section - Optional
    // call for creating a setting - Required
    // call for creating a control - Required
}
add_action( 'customize_register', 'tornadu_customize_register' );

The code of the setting for the control takes a default value and a sanitize_callback function.

$wp_customize->add_setting( 'setting_id'
     array(
        'default' => true // required - for a chekbox control
        'sanitize_callback' => 'custom_sanitize_callback' // required
     )
);

Depending on the type of the control associated with the setting, the values of the default parameter will be different.

For example, default value for a setting controlled with a checkbox control can be either true or false.

The sanitize_callback function ensures that the values entered for the setting are proper for that setting and sanitized before insertion to database.

The code of sanitize_callback function depends on the control that is associated with the setting. As with the default value, the callback function is different for different types of controls as given below –

Callback function for a setting managed by a text control

$wp_customize->add_setting( 'setting_id'
     array(
        'default' => 'any text value'// required - for a text control
        'sanitize_callback' => 'wp_filter_nohtml_kses' // required
     )
);

Here wp_filter_nohtml_kses is an inbuilt WordPress function that filters the input, removes any html present in the value and returns a text string. In place of the inbuilt function, we can also use any custom function.

Callback function for a setting managed by a checkbox control –

$wp_customize->add_setting( 'setting_id'
     array(
        'default' => true // required - true/false
        'sanitize_callback' => 'custom_sanitize_callback' // required
     )
);

function custom_sanitize_callback( $input ) {
   //returns true if checkbox is checked
   return ( isset( $input ) && $input == true ? true : false );
}

The callback function checks to see if the input is a checked value and returns true or false which is then entered to the database as the theme setting.

Callback function for a setting managed by a select control –

$wp_customize->add_setting( 'setting_id'
     array(
        'default' => 'any value from choices list in the control '// required 
        'sanitize_callback' => 'custom_sanitize_callback' // required
     )
);

function custom_sanitize_callback( $input, $setting ) {
   // the input must be a slug
   // permitted value lowercase alphanumeric characters, dashes and underscores
   $input = sanitize_key( $input );
  
   // list of possible select options 
   $choices = $setting->manager->get_control( $setting->id )->choices;
                              
   //return input if value is valid or return default option
   return ( array_key_exists( $input, $choices ) ? $input : $setting->default );                
}

In this case the callback function takes two parameters, $input and $setting. The input value is then sanitized using inbuilt sanitize_key function.

Then the list of options in the select array is extracted using the setting manager.

At last the input is compared with the list of select options and if the value is in the array then the value is returned. Else the default value is returned.

Callback function for a setting managed by a radio control

$wp_customize->add_setting( 'setting_id'
     array(
        'default' => 'red' // required - example value from Choices array in control
        'sanitize_callback' => 'custom_sanitize_callback' // required
     )
);

function custom_sanitize_callback( $input, $setting ) {
    // input must be a slug
    // permitted values - lowercase alphanumeric characters, dashes and underscores
    $input = sanitize_key($input);
  
    //get the list of possible radio box options 
    $choices = $setting->manager->get_control( $setting->id )->choices;
                              
    //return input if valid or return default option
    return ( array_key_exists( $input, $choices ) ? $input : $setting->default );                                
}

The sanitize_callback function of a radio control managed theme setting is similar to that of a select control.

It checks the input against an array of choices and returns the selected value if present or returns the default value from the setting.

Callback function for a setting managed by an email control

  $wp_customize->add_setting( 'setting_id', 
       array(
          'sanitize_callback' => 'sanitize_email' 
       )
  );

The sanitize_callback for a theme setting controlled by an email control is quite easy. It uses the inbuilt sanitize_email to strip out special characters and return a valid email only. But you can replace this with a custom function also.

Callback function for a setting managed by a url control

 $wp_customize->add_setting( 'setting_id', 
       array(
          'sanitize_callback' => 'esc_url_raw' 
       )
  );

The sanitize_callback takes an inbuild function esc_url_raw to strip the value of all special characters and return an Url. But you can replace it with a custom function that returns a valid Url.

Callback function for a setting managed by a number control –

 $wp_customize->add_setting( 'setting_id', 
      array(
          'sanitize_callback' => 'absint' 
      )
  );

The callback inbuilt function absint returns a non-negative integer value. You can replace it with a custom function that returns a positive integer.

Callback function for a setting managed by a file input control –

 function custom_sanitize_callback( $file, $setting ) {
          
      // the allowed file types
      $mimes = array(
                'jpg|jpeg|jpe' => 'image/jpeg',
                'gif'          => 'image/gif',
                'png'          => 'image/png'
      );
              
     // check file type from file name
     $file_ext = wp_check_filetype( $file, $mimes );
              
     // if file has a valid mime type return the file, else return default
     return ( $file_ext['ext'] ? $file : $setting->default );
}

 $wp_customize->add_setting( 'setting_id', 
      array(

        'default' => 'default file location' // optional
        'sanitize_callback' => 'custom_sanitize_callback' // required
      )
 );

The file upload control is basically used to set theme setting value for an image.

The function checks for a few permitted file type extensions, returns the file for upload if it is a valid file or returns the default file path.

Callback function for a setting managed by textarea control

 $wp_customize->add_setting( 'setting_id', // required
      array(
         'default' => 'any arbitrary string' // optional
         'sanitize_callback' => 'wp_strip_all_tags' // required
      )
 );

The callback function wp_strip_all_tags strips all html tags from the input content and returns a string.

Callback function for a setting managed by color control

$wp_customize->add_setting( 'setting_id', // required
     array(
        'default' => '#000000',
        'sanitize_callback' => 'sanitize_hex_color' 
     )
);

The callback function uses an inbuilt sanitizer sanitize_hex_color, that checks for a valid hex color input. You can also use a custom sanitizer functions that returns a valid hex color.

Callback function for a theme managed by a html control –

$wp_customize->add_setting( 'setting_id', // required
     array( 
       'default' => 'any valid html value' // optional
       'sanitize_callback' => 'wp_kses_post' // required
     )
 );

The callback function wp_kses_post is inbuilt and keeps only valid html tags allowed in post content. A custom function that returns valid html tags can replace this inbuilt function.