搜索全站
数据库 13 分钟阅读

WordPress 可复用区块与区块样板:一次制作全站复用的实操方法

同一个引导关注模块要在 800 篇文章里出现,改一次要改 800 次?本文讲清可复用区块和区块样板的区别与适用场景、创建与管理方法、用短代码和 PHP 调用的技巧,以及同步失效的排查方案。

U
UFO_PF 2017-02-28 · 阅读 13 分钟
Wo 数据库
阅读提示
本文约 4,883 字,预计阅读 13 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:改一句免责声明,改了三个晚上

真实的运维场景:站里有 800 篇文章,文末都有一个”免责声明 + 关注引导”模块。某天法务要求改一句措辞。

如果当初是复制粘贴的,那就要改 800 篇——后台改不现实,只能跑数据库批量替换,风险极高。

如果当初做成了可复用区块,改一处,800 篇全部同步更新,五分钟搞定。

这就是可复用区块存在的意义。WordPress 里有两个容易混淆的东西:可复用区块(Reusable Block)和区块样板(Block Pattern),这篇把两者讲清楚。

原理分析:两个东西,两种同步语义

对比项 可复用区块 区块样板
存储 wp_block 这个文章类型的记录,有 ID PHP 数组/JSON,注册在代码或 wp_block_patterns 里
修改是否同步到已插入处 同步(核心特性) 不同步(插入后是独立副本)
后台管理入口 有(”可复用区块”菜单) 无(在编辑器样板库里浏览)
能否用 PHP 输出 能 能(作为样板注册供插入)
典型用途 全站统一、需要统一改的模块 快速搭骨架的布局模板

一句话区分:要”改一处全站生效”用可复用区块;要”快速套一个版式”用区块样板。

技术上,可复用区块插入正文后,存的是一段引用:

<!-- wp:block {"ref":1234} /-->

ref 指向 wp_posts 里 post_type = wp_block 的那条记录。前台渲染时 WordPress 会去取这条记录的内容再渲染。所以它天然是同步的。

保姆级实操

一、创建可复用区块

  1. 在任意文章里做好这个模块(比如一个 Group 区块里含图标、标题、段落、按钮);
  2. 选中外层 Group 区块 → 右侧栏或工具栏三点菜单 → “添加到可复用区块”;
  3. 输入名字(比如”文末 CTA”)→ 保存。

之后名字会出现在区块插入器的”可复用”分类里。

二、管理与编辑

入口:后台左侧 可复用区块(wp-admin/edit.php?post_type=wp_block)。

也可以命令行看:

wp post list --post_type=wp_block --fields=ID,post_title,post_date

编辑某个可复用区块:

wp post edit 1234    # 在系统默认编辑器里打开

或者直接访问 wp-admin/post.php?post=1234&action=edit。

三、在任意位置用 PHP 输出可复用区块

这是最实用的技巧——可以把可复用区块放到主题模板里,比如每篇文章正文后自动追加:

add_filter( 'the_content', function( $content ) {
    if ( is_single() && in_the_loop() && is_main_query() ) {
        $block = get_post( 1234 );   // 可复用区块的 ID
        if ( $block && 'wp_block' === $block->post_type ) {
            $content .= do_blocks( $block->post_content );
        }
    }
    return $content;
});

do_blocks() 会解析并渲染区块 HTML。注意一定要用 do_blocks(),直接 echo $block->post_content 会输出原始的 <!-- wp:xxx --> 注释。

四、用短代码输出

如果你不想改主题,装插件或者自己注册一个短代码:

add_shortcode( 'reusable', function( $atts ) {
    $atts = shortcode_atts( array( 'id' => 0 ), $atts, 'reusable' );
    $id   = absint( $atts['id'] );
    $post = get_post( $id );
    if ( ! $post || 'wp_block' !== $post->post_type ) {
        return '';
    }
    return do_blocks( $post->post_content );
});

用法:[reusable id="1234"]。这样在小工具、经典编辑器、页面构建器的文本框里都能调用。

五、注册区块样板

样板适合做”版式模板”,比如一个”两栏图文”骨架。写在子主题里:

add_action( 'init', function() {
    register_block_pattern(
        'mmf/feature-box',
        array(
            'title'       => '图文特性卡片',
            'description' => '左侧图标右侧文案的特性卡片',
            'categories'  => array( 'text' ),
            'content'     => '<!-- wp:group {"className":"mmf-feature"} -->
<div class="wp-block-group mmf-feature"><!-- wp:columns -->
<div class="wp-block-columns"><!-- wp:column {"width":"20%"} -->
<div class="wp-block-column" style="flex-basis:20%"><!-- wp:paragraph {"align":"center","style":{"typography":{"fontSize":40}}} -->
<p style="font-size:40px;text-align:center">????</p>
<!-- /wp:paragraph --></div>
<!-- /wp:column -->

<!-- wp:column {"width":"80%"} -->
<div class="wp-block-column" style="flex-basis:80%"><!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading">特性标题</h3>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>这里写特性描述文字。</p>
<!-- /wp:paragraph --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:group -->',
        )
    );
});

注册后,编辑器里点”样板”图标就能看到并一键插入。

取消 WordPress 官方自带的样板(很多是英文场景,用不上):

add_action( 'init', function() {
    remove_theme_support( 'core-block-patterns' );
}, 9 );

六、导出导入可复用区块(换站/多站同步)

可复用区块本质是 wp_block 类型的文章,可以用标准导出:

wp post list --post_type=wp_block --format=ids
# 导出
wp export --dir=/tmp/ --post_type=wp_block --filename_format=blocks.xml
# 在目标站导入(需要 WordPress Importer 插件)
wp import /tmp/blocks.xml --authors=create

常见踩坑与失败案例

  1. 案例一:改了可复用区块但前台没变。原因:站点开了页面缓存(WP Rocket / 宝塔静态缓存),缓存没刷新。跑 wp rocket clean 或清缓存插件。
  2. “转换为常规区块”误操作:在已插入的区块上点了这个,同步关系就断了。之后改动不再传播,且没有提示。培训编辑时一定要强调这一点。
  3. 案例二:某站把 CTA 模块做成样板而不是可复用区块,改文案时 800 篇全没同步,最后只能跑 wp search-replace 批量替换,还破坏了几个区块的 JSON。判断标准很简单:需要同步就用可复用区块。
  4. 可复用区块在多语言站的表现:WPML/Polylang 对 wp_block 的处理不一致。Polylang 需要开启”同步可复用区块”选项,否则每种语言要单独建一个。建议 CTA 类的模块直接做成短代码,跨语言更可控。
  5. do_blocks() 输出为空:通常是可复用区块的 post_status 不是 publish(草稿状态前台取不到)。检查:

bash
wp post get 1234 --field=post_status

  1. 可复用区块里的图片:图片存在媒体库,换域名时同样要做 wp search-replace,否则同步更新的模块里全是裂图。
  2. 删除可复用区块后正文报错:正文里残留 <!-- wp:block {"ref":1234} /--> 但记录已删,前台输出为空,编辑时会提示”区块已删除”。用 SQL 清理:

sql
UPDATE wp_posts SET post_content = REGEXP_REPLACE(post_content, '<!-- wp:block \\{"ref":1234\\} /-->', '')
WHERE post_content LIKE '%wp:block%1234%';

MySQL 8.0 才有 REGEXP_REPLACE,5.7 要导出来处理。

总结

可复用区块和区块样板的取舍一句话说清:要”改一处全站生效”用可复用区块,要”快速套版式”用区块样板。可复用区块本质是 wp_block 类型的文章,插入正文存的是 {"ref":ID} 引用,所以天然同步;用 do_blocks() 可以在主题任意位置输出,做成短代码后连经典编辑器和页面构建器都能调用。两个必须记住的坑:别误点”转换为常规区块”,改完记得清页面缓存。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。