最近在整理博客写作流程时,又遇到了一个影响效率的小问题。
虽然每次只需要多点击几下,但由于我几乎每天都会写技术博客,长期下来,这种重复操作就变成了一个值得优化的地方。
最终,我通过分析 Gutenberg Block 的注册机制,并结合 WPCode,实现了保留 SyntaxHighlighter Evolved 历史文章兼容性的同时,让新文章自动转换为 Code Block Pro。
本文记录整个排查和解决过程,希望能给遇到类似问题的朋友提供一些参考。
问题背景
我的博客目前同时安装了两个代码高亮插件:
- SyntaxHighlighter Evolved:用于历史文章,已经使用多年。
- Code Block Pro:用于新文章,界面更加现代,支持更多功能,因此决定以后全部使用它。
但是在实际写作过程中,我发现了一个比较影响效率的问题。
当我从 ChatGPT 或 Markdown 文档中直接复制包含代码块的内容到 WordPress Gutenberg 编辑器时,系统默认创建的并不是 Code Block Pro,而是 SyntaxHighlighter Code。

随后,我不得不手动执行:
SyntaxHighlighter Code
↓
转换(Transform)
↓
Code Block Pro
如果一篇文章包含十几个代码块,就需要重复操作很多次。
虽然每次只需要几秒钟,但长期来看,非常影响写作效率。
为什么不能直接卸载 SyntaxHighlighter Evolved?
最开始,我想到的方案就是直接停用 SyntaxHighlighter Evolved。
但是查看历史文章后,很快发现这个方案不可行。
历史文章中的代码块实际上保存为:
<!-- wp:syntaxhighlighter/code {"language":"yaml"} -->
<pre class="wp-block-syntaxhighlighter-code">
...
</pre>
<!-- /wp:syntaxhighlighter/code -->
也就是说,我的历史文章已经全部依赖于 syntaxhighlighter/code 这个 Gutenberg Block。
如果直接停用插件,虽然文章内容不会丢失,但代码高亮效果将全部失效。
因此,最终确定原则:
历史文章保持不动,新文章继续使用 Code Block Pro。
分析 Gutenberg Block
为了找到真正的问题,我打开浏览器开发者工具,在 Console 中执行:
wp.blocks.getBlockTypes().map(x => x.name)
结果发现,编辑器中同时注册了三个代码块:
core/code
syntaxhighlighter/code
kevinbatdorf/code-block-pro
继续查看 SyntaxHighlighter Block:
wp.blocks.getBlockType("syntaxhighlighter/code")
发现它注册了如下转换规则:
transforms: {
from: [
{
type: "enter"
},
{
type: "raw"
},
{
type: "block"
}
]
}
其中最关键的是:
type: "raw"
这意味着,当我粘贴 Markdown 或 HTML 中的代码块时,会优先被 SyntaxHighlighter 接管,因此自动生成 SyntaxHighlighter Code Block。
而 Code Block Pro 本身并没有注册对应的 raw 转换规则,所以无法自动接管粘贴行为。
最终解决方案
既然不能修改历史文章,也不希望卸载 SyntaxHighlighter,那么思路就变成了:
仅修改 Gutenberg 编辑器行为,不影响前台显示。
最终,我使用 WPCode 添加了一个后台专用 PHP Snippet。
该 Snippet 会监听页面中新创建的:
core/codesyntaxhighlighter/code
随后自动转换为:
kevinbatdorf/code-block-pro
整个过程完全自动完成。
WPCode 配置如下:

名称:
[WP] Editor - 自动转换为 Code Block Pro
配置:
- Code Type:PHP Snippet
- Insert Method:Auto Insert
- Location:Admin Only
由于仅在后台编辑器运行,因此不会影响前台页面,也不会影响历史文章。
完整代码如下:
/**
* 后台编辑器:新粘贴/新插入的 core/code 或 syntaxhighlighter/code
* 自动转换为 Code Block Pro。
* 不处理打开文章时已经存在的历史代码块。
*/
add_action('enqueue_block_editor_assets', function () {
wp_add_inline_script(
'wp-blocks',
<<<JS
wp.domReady(function () {
if (!wp.data || !wp.blocks) return;
const TARGET = 'kevinbatdorf/code-block-pro';
const SOURCES = ['core/code', 'syntaxhighlighter/code'];
let knownClientIds = new Set();
let initialized = false;
let converting = false;
function flattenBlocks(blocks, result = []) {
blocks.forEach(function (block) {
result.push(block);
if (block.innerBlocks && block.innerBlocks.length) {
flattenBlocks(block.innerBlocks, result);
}
});
return result;
}
function getAllBlocks() {
return flattenBlocks(
wp.data.select('core/block-editor').getBlocks()
);
}
function rememberExistingBlocks() {
getAllBlocks().forEach(function (block) {
knownClientIds.add(block.clientId);
});
initialized = true;
}
setTimeout(rememberExistingBlocks, 1200);
wp.data.subscribe(function () {
if (!initialized || converting) return;
const blocks = getAllBlocks();
const candidates = blocks.filter(function (block) {
return SOURCES.includes(block.name) && !knownClientIds.has(block.clientId);
});
if (!candidates.length) {
blocks.forEach(function (block) {
knownClientIds.add(block.clientId);
});
return;
}
converting = true;
candidates.forEach(function (block) {
let converted = null;
if (wp.blocks.switchToBlockType) {
converted = wp.blocks.switchToBlockType(block, TARGET);
}
if (Array.isArray(converted)) {
converted = converted[0];
}
if (!converted && wp.blocks.createBlock) {
const attrs = block.attributes || {};
const code = attrs.code || attrs.content || attrs.text || '';
const language = attrs.language || attrs.lang || 'text';
converted = wp.blocks.createBlock(TARGET, {
code: code,
language: language
});
}
if (converted) {
wp.data.dispatch('core/block-editor').replaceBlock(block.clientId, converted);
knownClientIds.add(converted.clientId);
}
});
setTimeout(function () {
getAllBlocks().forEach(function (block) {
knownClientIds.add(block.clientId);
});
converting = false;
}, 300);
});
});
JS
);
});最终效果
添加 Snippet 后,再次测试。
直接将 ChatGPT 生成的 Markdown 内容粘贴到编辑器中:
以前:
Ctrl + V
↓
SyntaxHighlighter Code
↓
Transform
↓
Code Block Pro
现在:
Ctrl + V
↓
Code Block Pro
整个过程已经实现自动完成。

目前唯一的小问题是:
Code Block Pro 默认会继承上一次使用的语言,例如上一篇文章选择的是 Go,那么下一次新建代码块时默认仍然是 Go。
不过,对于我的写作习惯来说,这已经完全可以接受。
通常一篇文章主要围绕一种语言展开,例如:
- Go
- PHP
- Bash
- YAML
因此,只需要偶尔修改个别代码块的语言即可,相比之前已经节省了大量重复操作。
总结
这次优化解决的并不是一个复杂的问题。
它只是省掉了每篇文章中一次又一次重复点击的操作。
但是,对于长期坚持写技术博客的人来说,这类高频重复动作,往往才是最值得优化的地方。
整个优化过程中,我没有修改插件源码,也没有迁移历史文章,而是利用 Gutenberg Block API、浏览器开发者工具以及 WPCode,对编辑器行为进行了定制。
最终实现了:
- 保留 SyntaxHighlighter Evolved 的历史文章兼容性;
- 新文章默认使用 Code Block Pro;
- 不影响前台显示;
- 明显提升日常写作效率。
以后如果再遇到类似问题,我也会优先考虑:
先分析 Gutenberg Block 的工作机制,再决定是否通过 WPCode 对编辑器行为进行定制,而不是急着更换插件或者修改历史数据。
很多时候,只需要几十行代码,就能够让日常写作流程变得更加顺畅。
我是拥有 15+ 年经验的 PHP / Go 后端工程师。如需以下服务,欢迎联系我(更多介绍请查看 关于我 & 合作):
- ✅ PHP / Go 项目开发与维护
- ✅ 系统架构设计与技术咨询
- ✅ 网站性能优化与故障排查
- ✅ Linux 服务器部署与运维
- ✅ 网络环境优化与远程支持
- ✅ 长期技术顾问合作
微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan

发表回复