You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否根据预览页面条件切换Customizer控件的transport机制?

在WordPress Customizer中动态切换控件的Transport属性

绝对可以实现你的需求!WordPress Customizer的JS API和PHP钩子组合起来,就能轻松根据当前预览页面的状态动态调整控件的transport属性,既保证预览体验流畅,又能在需要时触发正确的刷新行为。

针对你提到的摘要长度设置场景,我给你一套具体的实现方案:

一、核心思路

  1. 默认优先用postMessage:大部分页面(比如单页、归档页设为显示完整内容时)不需要刷新,用postMessage实现无刷新预览。
  2. 动态切换为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:17:39