Can I change a control’s transport in Customizer depending on the previewed page?

The question:

I have a theme with an option for setting the excerpt length for generated excerpts. Is there a way in the Customizer of conditionally changing the transport mechanism, depending on whether the preview page is showing excerpts?

For example, I have another option that controls whether full content or excerpts are shown on archive pages, but the search page always shows excerpts. So I would prefer to not incur the whole page refresh if no excerpts are being previewed, but if it’s the search page or the other option is set to show excerpts, I would need to use refresh when the excerpt length is changed.

Or is this even worth the trouble of extra code?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Yes, you can change the transport of a registered setting dynamically after the page loads. And actually the active_callback can be used in conjunction with JS to change the transport instead of causing the control to be hidden.

Assuming you have registered a control with the ID of excerpt_length, and you have registered a setting and control as follows:

$wp_customize->add_setting( 'excerpt_length', array(
    'transport'         => 'refresh',
    'sanitize_callback' => function( $value ) {
        return intval( $value );
) );

$wp_customize->add_control( 'excerpt_length', array(
    'label'           => __( 'Excerpt length', 'example' ),
    'section'         => 'something',
    'type'            => 'number',
    'active_callback' => function() {
        // Admin check is for initial state in customize.php.
        return is_admin() || is_archive() || ( is_home() && ! is_front_page() );
) );

Then you can enqueue some JS for the Customizer controls app (at customize_controls_enqueue_scripts) which overrides the behavior for when the active state changes, like so to toggle the setting’s transport when active state changes instead of toggling the visibility of control:

wp.customize.control( 'excerpt_length', function( control ) {
    control.onChangeActive = function( active ) {
        control.setting.transport = active ? 'refresh' : 'postMessage';
} );

There’s other ways to do it, but this is probably the least amount of code.

Method 2

I didn’t find any solution for this. But I would suggest you to use active_callback parameter such that if another option that controls full content or excerpts shows full content and the page previewed is other than search page, hide the control that controls the excerpt length.

I guess this would be the better approach as you do want to show the relevent controls as per the previewed page.

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment