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.