WP_Customize_Control
The UI element class for the Customizer. Controls provide the interface for users to modify settings, including input fields, dropdowns, color pickers, and media selectors.
File: wp-includes/class-wp-customize-control.php
Since: WordPress 3.4.0
Class Synopsis
#[AllowDynamicProperties]
class WP_Customize_Control {
protected static $instance_count = 0; // Instance counter
public $instance_number; // Instance order
public $manager; // WP_Customize_Manager
public $id; // Control ID
public $settings; // All linked settings
public $setting = 'default'; // Primary setting
public $capability; // Required capability
public $priority = 10; // Display order
public $section = ''; // Parent section ID
public $label = ''; // Control label
public $description = ''; // Control description
public $choices = array(); // Options for select/radio
public $input_attrs = array(); // HTML input attributes
public $allow_addition = false; // Allow adding content
public $type = 'text'; // Control type
public $active_callback = ''; // Active callback
public $json = array(); // JSON export data
}
Constructor
public function __construct(
WP_Customize_Manager $manager,
string $id,
array $args = array()
)
Arguments
| Argument | Type | Default | Description |
|---|---|---|---|
settings |
string|array |
ID | Setting ID(s) to link |
setting |
string |
'default' |
Primary setting key |
capability |
string |
'' |
Override capability (usually inherited) |
priority |
int |
10 |
Display order |
section |
string |
'' |
Parent section ID (required) |
label |
string |
'' |
Control label |
description |
string |
'' |
Control description |
choices |
array |
array() |
Options for select/radio |
input_attrs |
array |
array() |
HTML attributes |
allow_addition |
bool |
false |
Allow adding (dropdown-pages) |
type |
string |
'text' |
Control type |
active_callback |
callable |
'' |
Visibility callback |
Built-in Control Types
Basic Types (via type argument)
| Type | Description |
|---|---|
text |
Text input (default) |
checkbox |
Single checkbox |
textarea |
Multi-line text |
radio |
Radio buttons (requires choices) |
select |
Dropdown select (requires choices) |
dropdown-pages |
WordPress page selector |
email |
Email input |
url |
URL input |
number |
Number input |
hidden |
Hidden field |
date |
Date input |
Examples
// Text input
$wp_customize->add_control( 'site_title', array(
'label' => __( 'Site Title' ),
'section' => 'title_tagline',
'type' => 'text',
) );
// Checkbox
$wp_customize->add_control( 'show_title', array(
'label' => __( 'Display Site Title' ),
'section' => 'title_tagline',
'type' => 'checkbox',
) );
// Select dropdown
$wp_customize->add_control( 'layout', array(
'label' => __( 'Layout' ),
'section' => 'layout_section',
'type' => 'select',
'choices' => array(
'left' => __( 'Left Sidebar' ),
'right' => __( 'Right Sidebar' ),
'full' => __( 'Full Width' ),
),
) );
// Radio buttons
$wp_customize->add_control( 'blog_style', array(
'label' => __( 'Blog Style' ),
'section' => 'blog_section',
'type' => 'radio',
'choices' => array(
'grid' => __( 'Grid' ),
'list' => __( 'List' ),
),
) );
// Textarea
$wp_customize->add_control( 'footer_text', array(
'label' => __( 'Footer Text' ),
'section' => 'footer_section',
'type' => 'textarea',
'input_attrs' => array(
'rows' => 5,
),
) );
// Number with attributes
$wp_customize->add_control( 'posts_per_page', array(
'label' => __( 'Posts Per Page' ),
'section' => 'blog_section',
'type' => 'number',
'input_attrs' => array(
'min' => 1,
'max' => 50,
'step' => 1,
),
) );
Specialized Control Classes
WP_Customize_Color_Control
Color picker with alpha support:
$wp_customize->add_control( new WP_Customize_Color_Control(
$wp_customize,
'header_color',
array(
'label' => __( 'Header Color' ),
'section' => 'colors',
)
) );
WP_Customize_Media_Control
Media library attachment selector:
$wp_customize->add_control( new WP_Customize_Media_Control(
$wp_customize,
'featured_video',
array(
'label' => __( 'Featured Video' ),
'section' => 'media_section',
'mime_type' => 'video',
)
) );
WP_Customize_Image_Control
Image uploader:
$wp_customize->add_control( new WP_Customize_Image_Control(
$wp_customize,
'logo',
array(
'label' => __( 'Logo' ),
'section' => 'title_tagline',
)
) );
WP_Customize_Upload_Control
File uploader:
$wp_customize->add_control( new WP_Customize_Upload_Control(
$wp_customize,
'custom_file',
array(
'label' => __( 'Upload File' ),
'section' => 'files_section',
)
) );
WP_Customize_Cropped_Image_Control
Image with cropping:
$wp_customize->add_control( new WP_Customize_Cropped_Image_Control(
$wp_customize,
'banner_image',
array(
'label' => __( 'Banner Image' ),
'section' => 'header_section',
'width' => 1200,
'height' => 400,
'flex_width' => true,
'flex_height' => false,
)
) );
WP_Customize_Code_Editor_Control
Syntax-highlighted code editor:
$wp_customize->add_control( new WP_Customize_Code_Editor_Control(
$wp_customize,
'custom_css_control',
array(
'label' => __( 'Custom CSS' ),
'section' => 'custom_css',
'code_type' => 'text/css',
'input_attrs' => array(
'aria-describedby' => 'custom-css-description',
),
)
) );
WP_Customize_Date_Time_Control
Date/time picker:
$wp_customize->add_control( new WP_Customize_Date_Time_Control(
$wp_customize,
'event_date',
array(
'label' => __( 'Event Date' ),
'section' => 'events_section',
'include_time' => true,
'twelve_hour_format' => true,
)
) );
Core Methods
active()
Checks if the control is active.
final public function active(): bool
active_callback()
Default callback returning true.
public function active_callback(): true
value()
Gets the setting’s value.
final public function value( string $setting_key = 'default' ): mixed
check_capabilities()
Validates user can use this control.
final public function check_capabilities(): bool
enqueue()
Enqueues control-specific scripts/styles.
public function enqueue(): void
Override in custom controls:
public function enqueue() {
wp_enqueue_script( 'my-control-js', get_template_directory_uri() . '/js/control.js' );
wp_enqueue_style( 'my-control-css', get_template_directory_uri() . '/css/control.css' );
}
json() / to_json()
Gets/prepares data for JavaScript.
public function json(): array
public function to_json(): void
get_content()
Gets the control’s HTML content.
final public function get_content(): string
maybe_render()
Checks capabilities and renders.
final public function maybe_render(): void
render()
Renders the control wrapper.
protected function render(): void
render_content()
Renders the control’s content.
protected function render_content(): void
get_link()
Gets the data-link attribute for a setting.
public function get_link( string $setting_key = 'default' ): string
link()
Outputs the data-link attribute.
public function link( string $setting_key = 'default' ): void
input_attrs()
Renders custom input attributes.
public function input_attrs(): void
print_template()
Prints the JS template.
final public function print_template(): void
content_template()
Underscore.js template for content.
protected function content_template(): void
Creating Custom Controls
Basic Custom Control
class My_Range_Control extends WP_Customize_Control {
public $type = 'range';
public function render_content() {
?>
<label>
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<input type="range"
<?php $this->input_attrs(); ?>
value="<?php echo esc_attr( $this->value() ); ?>"
<?php $this->link(); ?>>
</label>
<?php
}
}
// Usage
$wp_customize->add_control( new My_Range_Control(
$wp_customize,
'opacity',
array(
'label' => __( 'Opacity' ),
'section' => 'my_section',
'input_attrs' => array(
'min' => 0,
'max' => 100,
'step' => 5,
),
)
) );
JS-Rendered Control
class My_Advanced_Control extends WP_Customize_Control {
public $type = 'my-advanced';
public function enqueue() {
wp_enqueue_script(
'my-advanced-control',
get_template_directory_uri() . '/js/my-control.js',
array( 'customize-controls' ),
'1.0',
true
);
}
public function to_json() {
parent::to_json();
$this->json['myCustomData'] = $this->get_custom_data();
}
protected function content_template() {
?>
<label>
<# if ( data.label ) { #>
<span class="customize-control-title">{{ data.label }}</span>
<# } #>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<div class="my-advanced-control-content">
<!-- Custom template -->
</div>
</label>
<?php
}
}
// Register the type for JS rendering
$wp_customize->register_control_type( 'My_Advanced_Control' );
Multiple Settings
Controls can link to multiple settings:
$wp_customize->add_control( 'background_position', array(
'label' => __( 'Background Position' ),
'section' => 'background_image',
'settings' => array(
'x' => 'background_position_x',
'y' => 'background_position_y',
),
) );
Access in template:
<input type="text" <?php $this->link( 'x' ); ?>>
<input type="text" <?php $this->link( 'y' ); ?>>
Active Callbacks
Control visibility based on context:
$wp_customize->add_control( 'sidebar_position', array(
'label' => __( 'Sidebar Position' ),
'section' => 'layout_section',
'type' => 'select',
'choices' => array( 'left' => 'Left', 'right' => 'Right' ),
'active_callback' => function( $control ) {
return $control->manager->get_setting( 'show_sidebar' )->value();
},
) );
Input Attributes
Add custom HTML attributes:
$wp_customize->add_control( 'custom_width', array(
'label' => __( 'Width' ),
'section' => 'dimensions',
'type' => 'number',
'input_attrs' => array(
'min' => 100,
'max' => 2000,
'step' => 10,
'class' => 'my-custom-class',
'placeholder' => __( 'Enter width...' ),
'data-unit' => 'px',
),
) );
Complete Example
add_action( 'customize_register', function( $wp_customize ) {
// Add section
$wp_customize->add_section( 'hero_section', array(
'title' => __( 'Hero Section' ),
) );
// Show/hide toggle
$wp_customize->add_setting( 'show_hero', array(
'default' => true,
) );
$wp_customize->add_control( 'show_hero', array(
'label' => __( 'Show Hero Section' ),
'section' => 'hero_section',
'type' => 'checkbox',
) );
// Hero title
$wp_customize->add_setting( 'hero_title', array(
'default' => 'Welcome',
'sanitize_callback' => 'sanitize_text_field',
) );
$wp_customize->add_control( 'hero_title', array(
'label' => __( 'Hero Title' ),
'section' => 'hero_section',
'type' => 'text',
'active_callback' => function( $control ) {
return $control->manager->get_setting( 'show_hero' )->value();
},
) );
// Hero image
$wp_customize->add_setting( 'hero_image' );
$wp_customize->add_control( new WP_Customize_Image_Control(
$wp_customize,
'hero_image',
array(
'label' => __( 'Hero Image' ),
'section' => 'hero_section',
'active_callback' => function( $control ) {
return $control->manager->get_setting( 'show_hero' )->value();
},
)
) );
// Hero overlay color
$wp_customize->add_setting( 'hero_overlay_color', array(
'default' => 'rgba(0,0,0,0.5)',
'sanitize_callback' => 'sanitize_text_field',
) );
$wp_customize->add_control( new WP_Customize_Color_Control(
$wp_customize,
'hero_overlay_color',
array(
'label' => __( 'Overlay Color' ),
'section' => 'hero_section',
'active_callback' => function( $control ) {
return $control->manager->get_setting( 'show_hero' )->value();
},
)
) );
} );