Skip to main content

Overview

The Customizer functions provide theme settings that users can modify through the WordPress Theme Customizer interface. These functions are located in /inc/customizer.php and handle live preview, selective refresh, and JavaScript integration.
The Customizer allows users to preview changes in real-time before publishing, providing an intuitive interface for theme configuration.

zalbi_customize_register()

Configures the WordPress Theme Customizer with postMessage transport for instant preview updates.

Function Signature

function zalbi_customize_register( $wp_customize )

Parameters

$wp_customize
WP_Customize_Manager
required
WordPress Theme Customizer manager object that controls all customizer settings

Return Value

void
void
Modifies the customizer object directly

What It Does

This function enhances the default WordPress Customizer by:
  1. Enabling Live Preview - Changes transport method to postMessage for instant updates
  2. Selective Refresh - Refreshes only changed elements instead of entire page
  3. Better UX - Users see changes immediately without page reload

Modified Settings

transport
string
default:"postMessage"
Enables live preview for site title changes
Selective Refresh:
array(
    'selector'        => '.site-title a',
    'render_callback' => 'zalbi_customize_partial_blogname',
)
Changes update the site title link text without full page refresh.
transport
string
default:"postMessage"
Enables live preview for site description/tagline
Selective Refresh:
array(
    'selector'        => '.site-description',
    'render_callback' => 'zalbi_customize_partial_blogdescription',
)
Updates only the tagline element when changed.
transport
string
default:"postMessage"
Enables live color preview for header text
Color changes apply instantly via JavaScript without refresh.

Implementation

function zalbi_customize_register( $wp_customize ) {
    $wp_customize->get_setting( 'blogname' )->transport         = 'postMessage';
    $wp_customize->get_setting( 'blogdescription' )->transport  = 'postMessage';
    $wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';

    if ( isset( $wp_customize->selective_refresh ) ) {
        $wp_customize->selective_refresh->add_partial(
            'blogname',
            array(
                'selector'        => '.site-title a',
                'render_callback' => 'zalbi_customize_partial_blogname',
            )
        );
        $wp_customize->selective_refresh->add_partial(
            'blogdescription',
            array(
                'selector'        => '.site-description',
                'render_callback' => 'zalbi_customize_partial_blogdescription',
            )
        );
    }
}
add_action( 'customize_register', 'zalbi_customize_register' );

Transport Methods Explained

postMessage

Fast: Updates via JavaScript without page reloadBest for: Text, colors, sizes that can change via JS

refresh

Reliable: Reloads entire preview paneBest for: Complex changes requiring PHP processing

Selective Refresh Benefits

1

User types new site title

Change detected in Customizer control
2

Partial refresh triggered

Only .site-title a element is targeted
3

Callback executed

zalbi_customize_partial_blogname() generates new content
4

Element updated

Only the site title updates - page doesn’t reload
Performance: Selective refresh is faster than full page refresh and provides better user experience.

zalbi_customize_partial_blogname()

Render callback for the selective refresh partial of the site title.

Function Signature

function zalbi_customize_partial_blogname()

Parameters

None

Return Value

void
void
Outputs the site name directly via bloginfo()

Purpose

This function is called by the Customizer when the site title changes in live preview mode. It outputs just the site name without any wrapper HTML.

Implementation

function zalbi_customize_partial_blogname() {
    bloginfo( 'name' );
}

Usage

This function is automatically called by the Customizer API when:
  • User modifies site title in Customizer
  • Selective refresh is supported
  • Live preview is active

Template Requirement

For selective refresh to work, your theme header must use the selector .site-title a:
<!-- header.php -->
<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; ?>
</div>
If your template uses a different selector (e.g., .logo-text), update the selector in zalbi_customize_register() to match.

zalbi_customize_partial_blogdescription()

Render callback for the selective refresh partial of the site tagline/description.

Function Signature

function zalbi_customize_partial_blogdescription()

Parameters

None

Return Value

void
void
Outputs the site description directly via bloginfo()

Purpose

Called by the Customizer to refresh only the site tagline when it changes, without reloading the entire preview.

Implementation

function zalbi_customize_partial_blogdescription() {
    bloginfo( 'description' );
}

Template Requirement

Your header template must include the .site-description element:
<!-- header.php -->
<div class="site-branding">
    <p class="site-title">
        <a href="<?php echo esc_url( home_url( '/' ) ); ?>">
            <?php bloginfo( 'name' ); ?>
        </a>
    </p>
    
    <?php
    $description = get_bloginfo( 'description', 'display' );
    if ( $description || is_customize_preview() ) :
        ?>
        <p class="site-description"><?php echo $description; ?></p>
    <?php endif; ?>
</div>
The is_customize_preview() check ensures the element exists even when tagline is empty, allowing Customizer to refresh it when text is added.

zalbi_customize_preview_js()

Enqueues the JavaScript file that handles live preview updates in the Customizer.

Function Signature

function zalbi_customize_preview_js()

Parameters

None

Return Value

void
void
Enqueues customizer.js for preview frame

Purpose

Loads JavaScript that:
  • Listens for Customizer setting changes
  • Updates preview elements in real-time
  • Handles postMessage transport for instant updates

Implementation

function zalbi_customize_preview_js() {
    wp_enqueue_script( 
        'zalbi-customizer', 
        get_template_directory_uri() . '/js/customizer.js', 
        array( 'customize-preview' ), 
        _S_VERSION, 
        true 
    );
}
add_action( 'customize_preview_init', 'zalbi_customize_preview_js' );

Script Details

handle
string
default:"zalbi-customizer"
Unique script identifier
src
string
Path to /js/customizer.js in theme directory
dependencies
array
default:"['customize-preview']"
Depends on WordPress Customizer preview API
version
string
default:"_S_VERSION"
Theme version for cache busting
Loads in footer for better performance

Customizer JavaScript Example

The enqueued /js/customizer.js file typically contains:
/**
 * File customizer.js.
 *
 * Theme Customizer enhancements for a better user experience.
 */

( function( $ ) {
    // Site title
    wp.customize( 'blogname', function( value ) {
        value.bind( function( newval ) {
            $( '.site-title a' ).text( newval );
        } );
    } );

    // Site description
    wp.customize( 'blogdescription', function( value ) {
        value.bind( function( newval ) {
            $( '.site-description' ).text( newval );
        } );
    } );

    // Header text color
    wp.customize( 'header_textcolor', function( value ) {
        value.bind( function( newval ) {
            if ( 'blank' === newval ) {
                $( '.site-title, .site-description' ).css( {
                    'clip': 'rect(1px, 1px, 1px, 1px)',
                    'position': 'absolute'
                } );
            } else {
                $( '.site-title, .site-description' ).css( {
                    'clip': 'auto',
                    'position': 'relative'
                } );
                $( '.site-title a, .site-description' ).css( {
                    'color': newval
                } );
            }
        } );
    } );
} )( jQuery );

How It Works

1

Customizer loads

User opens Customizer, preview frame loads with this script
2

Script registers listeners

wp.customize() binds to specific settings
3

User makes change

Modifies site title, tagline, or header color
4

JavaScript updates preview

Change instantly reflected without page reload
Only in Customizer: This script only loads in the Customizer preview pane, not on the public site.

Customizer Settings Summary

Built-in WordPress Settings Enhanced

Site Title

Setting: blognameTransport: postMessageSelector: .site-title a

Tagline

Setting: blogdescriptionTransport: postMessageSelector: .site-description

Header Color

Setting: header_textcolorTransport: postMessageUpdated: Via JavaScript

Custom Zalbi Settings

WhatsApp Button

Setting: zalbi_whatsapp_numberLocation: Defined in functions.phpSection: “Botón WhatsApp”Transport: refresh (requires page reload)

Extending the Customizer

Adding a New Setting with Live Preview

// In functions.php or inc/customizer.php

function zalbi_custom_settings( $wp_customize ) {
    // Add section
    $wp_customize->add_section( 'zalbi_colors', array(
        'title'    => __( 'Theme Colors', 'zalbi' ),
        'priority' => 30,
    ));
    
    // Add setting
    $wp_customize->add_setting( 'zalbi_accent_color', array(
        'default'           => '#FF6B6B',
        'transport'         => 'postMessage',
        'sanitize_callback' => 'sanitize_hex_color',
    ));
    
    // Add control
    $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, 'zalbi_accent_color', array(
        'label'    => __( 'Accent Color', 'zalbi' ),
        'section'  => 'zalbi_colors',
    )));
    
    // Add selective refresh
    if ( isset( $wp_customize->selective_refresh ) ) {
        $wp_customize->selective_refresh->add_partial( 'zalbi_accent_color', array(
            'selector'            => '.button, .accent',
            'container_inclusive' => false,
            'render_callback'     => function() {
                return get_theme_mod( 'zalbi_accent_color', '#FF6B6B' );
            },
        ));
    }
}
add_action( 'customize_register', 'zalbi_custom_settings' );

Corresponding JavaScript

// In js/customizer.js

// Accent color
wp.customize( 'zalbi_accent_color', function( value ) {
    value.bind( function( newval ) {
        $( '.button, .accent' ).css( 'background-color', newval );
    } );
} );

Using Settings in Templates

// Get Customizer value in template
$accent_color = get_theme_mod( 'zalbi_accent_color', '#FF6B6B' );

// Output inline styles
?>
<style>
    .button,
    .accent {
        background-color: <?php echo esc_attr( $accent_color ); ?>;
    }
</style>

Customizer API Reference

Core WordPress Functions Used

Retrieves an existing Customizer setting object to modify its properties.
$setting = $wp_customize->get_setting( 'blogname' );
$setting->transport = 'postMessage';
Creates a new section in the Customizer sidebar.
$wp_customize->add_section( 'section_id', array(
    'title'       => 'Section Title',
    'description' => 'Section description',
    'priority'    => 30,
));
Registers a new Customizer setting.
$wp_customize->add_setting( 'setting_id', array(
    'default'           => 'default value',
    'transport'         => 'postMessage', // or 'refresh'
    'sanitize_callback' => 'sanitize_text_field',
));
Adds a UI control for a setting.
$wp_customize->add_control( 'control_id', array(
    'label'    => 'Control Label',
    'section'  => 'section_id',
    'settings' => 'setting_id',
    'type'     => 'text', // text, checkbox, radio, select, etc.
));
Registers a partial for selective refresh.
$wp_customize->selective_refresh->add_partial( 'setting_id', array(
    'selector'        => '.css-selector',
    'render_callback' => 'callback_function_name',
));

Helper Functions

get_theme_mod()
function
Retrieves a theme modification value
$value = get_theme_mod( 'setting_name', 'default_value' );
set_theme_mod()
function
Sets a theme modification value programmatically
set_theme_mod( 'setting_name', 'new_value' );
remove_theme_mod()
function
Removes a theme modification
remove_theme_mod( 'setting_name' );

Hooks Reference

customize_register
action
When: Customizer is being initializedUsed by: zalbi_customize_register(), zalbi_customize_whatsapp()Priority: 10 (default)
customize_preview_init
action
When: Customizer preview frame is loadingUsed by: zalbi_customize_preview_js()Purpose: Enqueue preview-specific scripts
theme_mod_{$name}
filter
Filters the value of a specific theme modification
add_filter( 'theme_mod_zalbi_whatsapp_number', function( $value ) {
    // Modify or validate the value
    return $value;
});

Troubleshooting

Live Preview Not Working

1

Check transport setting

Ensure setting uses 'transport' => 'postMessage'
2

Verify JavaScript is loaded

Check that customizer.js exists and is enqueued
3

Confirm selector matches

Partial selector must match actual HTML element
4

Test render callback

Ensure callback function exists and outputs correct content

Selective Refresh Not Updating

Common Issues:
  • Selector doesn’t match any elements in DOM
  • Render callback is missing or returns nothing
  • Element is inside a conditional that evaluates to false
  • JavaScript errors preventing listener registration
Debug Steps:
// In js/customizer.js, add console logging
wp.customize( 'setting_name', function( value ) {
    value.bind( function( newval ) {
        console.log( 'Setting changed to:', newval );
        $( '.selector' ).text( newval );
    } );
} );

Settings Not Saving

Check sanitization callback:
// Proper sanitization is required
$wp_customize->add_setting( 'my_setting', array(
    'sanitize_callback' => 'sanitize_text_field', // Must be valid
));

// Common sanitization callbacks:
// - sanitize_text_field
// - sanitize_email
// - sanitize_hex_color
// - esc_url_raw
// - absint
// - wp_kses_post

Best Practices

Use postMessage

Enable instant preview for better UX whenever possible

Selective Refresh

Update only changed elements instead of full page

Sanitize Everything

Always use proper sanitization callbacks for security

Provide Defaults

Every setting should have a sensible default value

Performance Tips

  1. Use Selective Refresh over full page refresh when possible
  2. Minimize JavaScript - Only update elements that changed
  3. Cache theme mods - Don’t call get_theme_mod() repeatedly
  4. Enqueue only in Customizer - Use customize_preview_init hook

Theme Setup

Core theme initialization and WordPress feature support

Template Tags

Display functions for post metadata and content

Build docs developers (and LLMs) love