Rediscover Theme Settings

With the WordPress Customizer

By: Anthony Skelton

ajskelton

Follow this Live Slideshow @

https://slides.com/ajskelton/customizer/live

The Customizer is everything.

- Matt Mullenweg

Add file for your Customizations



  require get_template_directory() . '/inc/customizer.php';

Modify the Customizer


 function ajs_customize_register( $wp_customize ) {

   // Do stuff with $wp_customize
 }

 add_action( 'customize_register', 'ajs_customize_register' );

Change the Customizer

Four main Customizer objects

Panels

Sections

Settings

Controls

Change the Customizer

Each Object has three methods

add_   get_   remove_


  $wp_customize->get_panel();
 
  $wp_customize->remove_section();
 
  $wp_customize->add_setting();
 
  $wp_customize->add_control();

Change the Customizer

$wp_customize->remove_


  $wp_customize->remove_setting( 'blogname');

Change the Customizer

$wp_customize->get_


  $wp_customize->get_setting( 'blogname' )
               ->transport = 'postMessage';

  $wp_customize->get_setting( 'blogdescription' )
               ->transport  = 'postMessage';

Adding to the Customizer

$wp_customize->add_panel


 $wp_customize->add_panel( 'panel_id', array(
     'priority'   	=> 10,
     'title'      	=> __( 'Panel Title' ), 
     'description'	=> __( 'Panel Description' ),
     'capability' 	=> 'edit_theme_options',
     'theme_supports'   => '',
 ) );

Adding to the Customizer

$wp_customize->add_section


 $wp_customize->add_section( 'section_id', array(
     'priority'        => 10,
     'title'           => __( 'Section Title' ),
     'description'     => __( 'Section Description' ),
     'panel'           => '',    
     'active_callback' => '',
 ) );

Adding to the Customizer

Default WordPress Sections

Title ID Priority (Order)
Site Title & Tagline title_tagline 20
Colors colors 40
Header Image header_image 60
Background Image background_image 80
Menus (Panel)* menus 100
Widgets (Panel) widgets 110
Static Front Page static_front_page 120

Adding to the Customizer

$wp_customize->add_setting


 $wp_customize->add_setting( 'setting_id', array(
   'type' => 'theme_mod',
   'capability' => 'edit_theme_options',
   'theme_supports' => '',
   'default' => '',
   'transport' => 'refresh',
   'sanitize_callback' => '',
   'validate_callback' => '',
 ) );

Adding to the Customizer

$wp_customize->add_setting

  • widget_*
  • sidebars_widgets[*]
  • nav_menu[*]
  • nav_menu

Don't Use These in your Setting ID

Adding to the Customizer

$wp_customize->add_control


 $wp_customize->add_control( 'setting_id', array(
   'priority' => 10,
   'label' => _( 'Control Label' ),
   'description' => _( 'Control Description' ),
   'type' => 'text',
   'section' => 'section_id',
   'input_attrs' => array(),
   'active_callback' => '',
 ) );

Adding to the Customizer

Types of Controllers

text textarea date
range url email
password hidden checkbox
radio select dropdown-pages
number time datetime
week search

theme_mod

vs.

option

Setting Type

'type' => 'option'

  • Stores each setting in the wp_options table
  • Setting ID = table row
  • Not recommended for themes

'type' => 'theme_mod'

  • Tied to each theme you activate
  • Stores each setting under theme_mods_THEMENAME
  • Default for all new settings

How the customizer saves data

Transport Property

Setting Transport

How the customizer previews new values

'transport' => 'refresh'

  • Default property
  • Full page refresh of entire front end
  • Accurate refresh with no extra code
  • Slow if lots of elements

'transport' => 'postMessage'

  • Any change no longer triggers page refresh
  • New value is sent to the frame, requires JavaScript to update the preview.
  • Very fast, but requires duplicate Javascript logic.

Transport

Refresh

postMessage

postMessage

Enqueue Javascript with custom_preview_init

Require customize-preview and jquery dependencies


 function ajs_preview_js() {
     wp_enqueue_script(
        'custom_css_preview',
        'path/to/file.js',
        array( 'customize-preview', 'jquery' )
     );
 }
 add_action( 'customize_preview_init', 'ajs_preview_js' );

postMessage

Use the wp.customize object

( function( $ ) {

  wp.customize( 'setting_id', function ( value ) {
    value.bind( function( to ) {
      $( '#custom-theme-css' ).html( to );
    } );
  } );

} )( jQuery );

Don't go overboard.

Save complicated changes for Selective Refresh

Selective Refresh

Selective Refresh

  • Only refresh the value that you change
  • Use existing PHP logic
 $wp_customize->selective_refresh->add_partial( 
     'partial_id',
     array(
         'settings' => 'partial_id'
         'selector' => '#css-selector',
         'container_inclusive' => false,
         'render_callback' => function() {
             // template tag or php logic
         },
         'fallback_refresh' => true
    )
 );

Register your partial

Selective Refresh

 $wp_customize->add_setting( 
     'backwardstext_setting_id',
     array(
         'capability' => 'edit_theme_options',
         'transport' => 'postMessage',
         'default' => 'Lorem Ipsum',
     )
 ); 

 $wp_customize->add_control( 
     'backwardstext_setting_id',
     array(
         'type' => 'text',
         'priority' => 10,
         'section' => 'custom_section', 
     )
 );

Selective Refresh

$wp_customize->selective_refresh->add_partial( 
    'backwardstext_setting_id',
    array(
        'selector' => '.backwards-text',
        'render_callback' => 'ajs_customizer_partial_backwardstext',
    )
);
function ajs_customizer_partial_backwardstext() {
    echo strrev(get_theme_mod('backwardstext_setting_id'));
}

Selective Refresh

Selective Refresh

Using Customizer Values

Usings Customizer Settings

get_theme_mod( 'SETTING-NAME', 'DEFAULT' );

get_option( 'OPTION-NAME', 'DEFAULT' );

Contextual Controls

Contextual Controls

When sections are shown based on Customizer Preview Windows location

Contextual Controls

Use a conditional tag name

'active_callback' => 'is_front_page'

Use your own function inline

'active_callback' => function() {
      return is_page();
 }

Needs to return a truthy value

Contextual Controls

Set context based on other Customizer Settings

Contextual Controls

Add active_callback to Control

'active_callback' => 'radio_callback'

Use WP_Customize_Control ( $control )

function radio_callback( $control ) {
    $radio_setting = $control->manager->get_setting('demo_radio_control')->value();
    $control_id = $control->id;

    if( $control_id == 'choice_a_text' && $radio_setting == 'a' ) return true;
    if( $control_id == 'choice_b_image' && $radio_setting == 'b' ) return true;

    return false;
}

Customizer

Sanitization

Customizer Sanitization

Use a WordPress Sanitization function

  • sanitize_text_field
  • sanitize_hex_color
  • is_email
  • absint
  • intval
  • strip_tags
'sanitize_callback' => 'sanitize_text_field'

Customizer Sanitization

Build your own sanitization function

$wp_customize->add_setting( 'radio_setting_id', array(
    'default' => 'blue',
    'sanitize_callback' => 'ajs_customizer_sanitize_radio',
) );

$wp_customize->add_control( 'radio_setting_id', array(
    'type' => 'radio',
    'section' => 'custom_section',.
    'label' => __( 'Custom Radio Selection' ),
    'description' => __( 'This is a custom radio input.' ),
    'choices' => array(
        'red' => __( 'Red' ),
        'blue' => __( 'Blue' ),
        'green' => __( 'Green' ),
    ),
) );

Customizer Sanitization

Build your own sanitization function

function ajs_customizer_sanitize_radio( $input ) {
    $valid = array(
        'red' => __( 'Red' ),
        'blue' => __( 'Blue' ),
	'green' => __( 'Green' ),
    );

    if( array_key_exists( $input, $valid ) ) {
	return $input;
    } else {
	return '';
    }
}

Customizer Validation

Customizer Validation

  • Customizer jumps to section with error on save attempt
  • Displays error messages below label
  • If invalid, save request fails, left transactional, returns dirty values to Customizer form fields
  • Validate before attempt to save to database

Customizer Validation

function validate_established_year( $validity, $value ) {
    $value = intval( $value );
    if ( empty( $value ) || ! is_numeric( $value ) ) {
        $validity->add( 'required', __( 'You must supply a valid year.' ) );
    } elseif ( $value < 1900 ) {
        $validity->add( 'year_too_small', __( 'Year is too old.' ) );
    } elseif ( $value > gmdate( 'Y' ) ) {
        $validity->add( 'year_too_big', __( 'Year is too new.' ) );
    }
    return $validity;
}

Use $validity and $value to add validation checks

'validate_callback' => 'validate_established_year'

Customizer Validation

Customizer Validation

Validation and Selective Refresh

  • Validates every time you change the value
  • If error occurs, preview reverts to last saved value
  • Once error has been fixed and validation passes the error notification will be removed

Customizer Validation

Validation and Selective Refresh

function ajs_established_year() {
    echo get_theme_mod('established_year');
}
$wp_customize->selective_refresh->add_partial(
    'established_year',
    array(
        'selector' => '.established-year',
        'render_callback' => 'ajs_established_year',
    )
);

Add Partial

Add function for render_callback

Customizer Validation

Validation and Selective Refresh

The Future

The Future of The Customizer

  • WordPress 4.7
  • Customize Changesets
  • Theme Preview and Installation
  • Customizing Posts

Happy Customizing

Rediscover Theme Settings with the WordPress Customizer

By Anthony Skelton

Rediscover Theme Settings with the WordPress Customizer

Anthony Skelton's WordCamp Sacramento talk on the WordPress Customizer

  • 4,132