能否根据预览页面条件切换Customizer控件的transport机制?
在WordPress Customizer中动态切换控件的Transport属性
绝对可以实现你的需求!WordPress Customizer的JS API和PHP钩子组合起来,就能轻松根据当前预览页面的状态动态调整控件的transport属性,既保证预览体验流畅,又能在需要时触发正确的刷新行为。
针对你提到的摘要长度设置场景,我给你一套具体的实现方案:
一、核心思路
- 默认优先用
postMessage:大部分页面(比如单页、归档页设为显示完整内容时)不需要刷新,用postMessage实现无刷新预览。 - 动态切换为
refresh:当预览页面是搜索页(始终显示摘要),或归档页设置为显示摘要时,把控件的transport改成refresh,确保修改摘要长度后预览能同步更新(如果你的摘要是PHP端生成的,刷新是最稳妥的方式;如果能通过JS即时修改预览,也可以保持postMessage并添加对应的预览更新逻辑)。
二、具体代码实现
1. PHP端:注册设置并传递预览页面数据
首先在主题的functions.php里注册你的自定义设置,并把当前预览页面的关键信息传递给JS:
add_action( 'customize_register', function( $wp_customize ) { // 注册摘要长度设置 $wp_customize->add_setting( 'excerpt_length', array( 'default' => 55, 'sanitize_callback' => 'absint', 'transport' => 'postMessage', // 默认无刷新 ) ); $wp_customize->add_control( 'excerpt_length', array( 'label' => __( '摘要长度', 'your-theme' ), 'section' => 'theme_content_settings', // 替换成你自己的设置区块 'type' => 'number', 'input_attrs' => array( 'min' => 10, 'max' => 200, ), ) ); // 注册归档页显示模式设置 $wp_customize->add_setting( 'archive_display_type', array( 'default' => 'excerpt', 'sanitize_callback' => 'sanitize_text_field', 'transport' => 'refresh', // 这个选项本身需要刷新生效 ) ); $wp_customize->add_control( 'archive_display_type', array( 'label' => __( '归档页显示内容', 'your-theme' ), 'section' => 'theme_content_settings', 'type' => 'select', 'choices' => array( 'excerpt' => __( '显示摘要', 'your-theme' ), 'full' => __( '显示完整内容', 'your-theme' ), ), ) ); } ); // 向Customizer预览脚本传递页面数据 add_action( 'customize_preview_init', function() { $page_info = array( 'is_search' => is_search(), 'is_archive' => is_archive(), 'archive_display' => get_theme_mod( 'archive_display_type', 'excerpt' ), ); wp_localize_script( 'customize-preview', 'ThemePreviewInfo', $page_info ); } );
2. JS端:动态切换Transport属性
创建一个customize-preview.js文件(放在主题的js目录下),然后在PHP里引入这个脚本:
add_action( 'customize_preview_init', function() { wp_enqueue_script( 'theme-customize-preview', get_template_directory_uri() . '/js/customize-preview.js', array( 'customize-preview' ), wp_get_theme()->get( 'Version' ), true ); } );
然后在customize-preview.js里编写逻辑:
jQuery( document ).ready( function( $ ) { // 等待Customizer预览加载完成 wp.customize.bind( 'preview-ready', function() { const excerptControl = wp.customize.control( 'excerpt_length' ); if ( ! excerptControl ) return; // 判断当前是否需要用refresh模式 function needRefresh() { // 搜索页始终需要 if ( ThemePreviewInfo.is_search ) return true; // 归档页且设置为显示摘要时需要 if ( ThemePreviewInfo.is_archive && ThemePreviewInfo.archive_display === 'excerpt' ) return true; // 其他情况用postMessage return false; } // 初始化transport属性 excerptControl.set( 'transport', needRefresh() ? 'refresh' : 'postMessage' ); // 监听归档页显示模式的变化,动态更新transport wp.customize( 'archive_display_type', function( setting ) { setting.bind( function( newVal ) { ThemePreviewInfo.archive_display = newVal; excerptControl.set( 'transport', needRefresh() ? 'refresh' : 'postMessage' ); } ); } ); // 监听预览页面切换(比如用户在Customizer里点选不同页面预览) wp.customize.preview.bind( 'active', function() { const previewBody = $( wp.customize.preview.targetWindow.document.body ); // 更新页面状态 ThemePreviewInfo.is_search = previewBody.hasClass( 'search' ); ThemePreviewInfo.is_archive = previewBody.hasClass( 'archive' ); // 如果切换到归档页,同步当前的显示模式设置 if ( ThemePreviewInfo.is_archive ) { ThemePreviewInfo.archive_display = wp.customize( 'archive_display_type' ).get(); } // 更新transport属性 excerptControl.set( 'transport', needRefresh() ? 'refresh' : 'postMessage' ); } ); } ); } );
3. 可选:添加postMessage预览更新逻辑
如果想在不需要刷新的页面也能即时看到摘要长度变化,可以在customize-preview.js里再加一段代码,用JS修改预览页面的摘要内容:
// 监听摘要长度变化,即时更新预览 wp.customize( 'excerpt_length', function( setting ) { setting.bind( function( newLength ) { // 只在不需要刷新的页面执行 if ( ! needRefresh() ) { $( '.entry-excerpt', wp.customize.preview.targetWindow.document ).each( function() { // 这里需要提前把原始摘要内容存在data属性里,比如在PHP渲染时添加: // <div class="entry-excerpt" data-original="<?php echo esc_attr( get_the_excerpt() ); ?>">...</div> const originalText = $( this ).data( 'original' ) || $( this ).text(); // 简单实现截断(实际项目建议用更严谨的单词截断逻辑) const truncated = originalText.substring( 0, newLength ) + ( originalText.length > newLength ? '...' : '' ); $( this ).text( truncated ); } ); } } ); } );
三、效果说明
- 当用户预览搜索页时,修改摘要长度控件会触发整页刷新,确保PHP生成的摘要正确更新。
- 当用户预览归档页且设置为显示摘要时,同样触发刷新。
- 当用户预览单页、归档页设置为显示完整内容时,修改摘要长度不会刷新页面,而是通过JS即时更新预览(如果加了上面的可选代码),体验更流畅。
内容的提问来源于stack exchange,提问作者Joy Reynolds
相关产品推荐
相关产品推荐

