WordPress 经典编辑器底部那一排按钮(b、i、link、code…),其实是可以用代码自己加的——加一个"一键插入代码高亮标签"的按钮,写技术文章时能省掉大量重复劳动。
但很多人在升级到 WordPress 6.0 之后发现:以前好好的自定义按钮,一夜之间全部消失了,控制台还报 QTags is not defined。这篇文章就把 Quicktags 的用法和这个坑一次讲透。
一、Quicktags 是什么
Quicktags 是 WordPress 自带的一个轻量 JS 库(wp-includes/js/quicktags.min.js),负责经典编辑器「文本」模式那一排工具栏。它提供一个全局对象 QTags,核心方法就是 QTags.addButton()。
两个前提要清楚:
- 只在经典编辑器的「文本 / HTML」模式出现,可视化模式下看不到;
- Gutenberg(区块编辑器)不加载 quicktags,所以按钮在区块编辑器里永远不会出现。
二、最小可用代码
把下面这段丢进主题的 functions.php(建议用子主题,否则主题更新会覆盖):
<?phpadd_action( 'admin_print_footer_scripts', 'my_quicktags', 11 );
function my_quicktags() {
if ( ! wp_script_is( 'quicktags' ) ) {
return;
}?><script>
QTags.addButton( 'my_h2', 'h2', '<h2>', '</h2>', '', '二级标题', 200 );
</script>
<?php}
刷新文章编辑页,切到「文本」模式,工具栏最后一排就会出现一个 h2 按钮:光标选中文字点一下,自动包上 <h2></h2>。
三、addButton 的七个参数
| # | 参数名 | 必填 | 说明 |
|---|---|---|---|
| 1 | id | 是 | 按钮唯一 ID,最终 DOM id 会被加上 qt_content_ 前缀。不要与默认按钮重名 |
| 2 | display | 是 | 按钮上显示的文字 |
| 3 | arg1 | 是 | 开始标签(也可传回调函数名) |
| 4 | arg2 | 否 | 结束标签。留空则该按钮是"选中包裹"型 |
| 5 | access_key | 否 | 已废弃,填 '' 即可,早年的快捷键功能现在完全不生效 |
| 6 | title | 否 | 鼠标悬停提示文字 |
| 7 | priority | 否 | 排位。1-9 第一排,11-19 第二排,21-29 第三排;不填会被挤到最后 |
关于 priority:1-9 是第一排、11-19 第二排、21-29 第三排。想让自己的按钮独占一排不跟默认按钮混在一起,直接填 200 以上,它们会整齐地排在工具栏末尾。
四、WP 6.0 后按钮集体消失:原因与修复
现象
升级到 WordPress 6.0 之后,自定义按钮一个都不显示,浏览器控制台报:
Uncaught ReferenceError: QTags is not defined根因
WP 6.0 调整了后台脚本的加载顺序,把 quicktags.min.js 的加载推后了。而 admin_print_footer_scripts 这个钩子的默认优先级是 10——你的内联脚本跑在 quicktags 之前,此时 QTags 这个全局对象还不存在,整段 JS 直接抛错中断,按钮自然一个都加不上。
这不是你代码写错了,是核心行为变了。
修复方法一:把优先级改成 11(最简单)
给 add_action 补第三个参数,值必须大于 10:
<?php// ↓ 关键:第三个参数 11add_action( 'admin_print_footer_scripts', 'my_quicktags', 11 );
再配合 wp_script_is( 'quicktags' ) 判断,在没有编辑器的后台页面直接跳过,避免无谓报错:
<?phpfunction my_quicktags() {
if ( ! wp_script_is( 'quicktags' ) ) {
return; // 当前页面没有经典编辑器,不输出脚本
}?><script>
QTags.addButton( 'my_h2', 'h2', '<h2>', '</h2>', '', '二级标题', 200 );
</script>
<?php}add_action( 'admin_print_footer_scripts', 'my_quicktags', 11 );
修复方法二:wp_add_inline_script(推荐,更规范)
把脚本挂到 quicktags 这个 handle 后面,WordPress 会保证它在 quicktags 加载完之后输出,从原理上杜绝顺序问题:
<?phpadd_action( 'admin_enqueue_scripts', function () {
wp_add_inline_script('quicktags',
"QTags.addButton( 'my_h2', 'h2', '<h2>', '</h2>', '', '二级标题', 200 );");
} );
好处有三个:不写死 <script> 标签、始终保证执行顺序、当其他插件移除 quicktags 时不会跟着报错。
修复方法三:独立 JS 文件 + 声明依赖
按钮多的时候最清爽。新建 js/my-quicktags.js:
QTags.addButton( 'my_h2', 'h2', '<h2>', '</h2>', '', '二级标题', 200 );
QTags.addButton( 'my_h3', 'h3', '<h3>', '</h3>', '', '三级标题', 201 );
然后在 functions.php 里注册,第二个数组声明依赖:
<?phpadd_action( 'admin_enqueue_scripts', function () {
wp_enqueue_script('my-quicktags',
get_template_directory_uri() . '/js/my-quicktags.js',
array( 'quicktags' ), // ← 声明依赖,保证加载顺序
'1.0',
true);
} );
五、Gutenberg 区块编辑器下怎么办
直接说结论:Gutenberg 页面根本不加载 quicktags,上面所有代码都不会生效,wp_script_is( 'quicktags' ) 会返回 false。
三条路,选一条:
- 装 Classic Editor 插件——最简单,装完本文所有代码原地复活;
- 用「自定义 HTML」区块——直接在区块里手写标签,不要按钮;
- 写区块编辑器扩展——用
enqueue_block_editor_assets挂一个真正的区块格式(Format API),这是另一套体系,工作量不小。
如果你的习惯是手写 HTML(尤其是技术站要贴代码块),方案 1 最省事。
六、实战:一套能直接用的按钮组
下面是本站正在用的配置,包含代码高亮标签按钮、标题、强调、图片,复制改改就能用:
<?php/*** 在文本编辑器工具栏追加自定义按钮** 【关键】add_action 第三个参数 11 —— WP 6.0 起 quicktags.min.js 推迟加载,* 优先级 10 时 QTags 尚未定义,会报 "QTags is not defined",按钮全部失效。*/add_action( 'admin_print_footer_scripts', 'eg_quicktags', 11 );
function eg_quicktags() {
if ( ! wp_script_is( 'quicktags' ) ) {
return;
}?><script type="text/javascript">
// —— 代码高亮标签(配合 GeSHi 系插件)——
QTags.addButton( 'eg_pre', 'pre', '<pre>\n\n</pre>', '', '', '普通 pre', 200 );
QTags.addButton( 'css_pre', 'pre-css', '<pre lang="css" line="1" escaped="true">\n\n</pre>', '', '', 'CSS 代码', 201 );
QTags.addButton( 'phs_pre', 'pre-php', '<pre lang="php" line="1" escaped="true">\n\n</pre>', '', '', 'PHP 代码', 202 );
QTags.addButton( 'html_pre', 'pre-html', '<pre lang="html4strict" line="1" escaped="true">\n\n</pre>', '', '', 'HTML 代码', 203 );
QTags.addButton( 'js_pre', 'pre-js', '<pre lang="javascript" line="1" escaped="true">\n\n</pre>', '', '', 'JS 代码', 204 );
QTags.addButton( 'csharp_pre','pre-c#', '<pre lang="csharp" line="1" escaped="true">\n\n</pre>', '', '', 'C# 代码', 205 );
QTags.addButton( 'lua_pre', 'pre-lua', '<pre lang="lua" line="1" escaped="true">\n\n</pre>', '', '', 'Lua 代码', 206 );
QTags.addButton( 'epl_pre', 'pre-epl', '<pre lang="epl" line="1" escaped="true">\n\n</pre>', '', '', '易语言代码', 207 );
// —— 排版 ——
QTags.addButton( 'p_p', 'p-zhy', '<p class="alert alert-info" role="alert"><strong>xxx </strong> ...... </p>', '', '', '提示段落', 208 );
QTags.addButton( 'h_2', 'h-2', '<h2><strong> xxx </strong></h2>', '', '', '二级标题', 209 );
QTags.addButton( 'h_3', 'h-3', '<h3><strong> xxx </strong></h3>', '', '', '三级标题', 210 );
QTags.addButton( 'h_4', 'h-4', '<h4><strong> xxx </strong></h4>', '', '', '四级标题', 211 );
QTags.addButton( 'strong', 'strong','<strong> xxx </strong>', '', '', '红色强调', 212 );
QTags.addButton( 'img_y', 'img', '<p><img class="img-thumbnail" src="" alt="" loading="lazy" /></p>', '', '', '插入图片', 213 );
</script>
<?php}
其中 <pre lang="epl"> 那个按钮,需要 GeSHi 侧有对应的 epl.php 语言文件才会真正着色,否则只会插入标签、前台显示为纯文本。
七、进阶:带输入框的按钮
第 3 个参数除了传标签字符串,还可以传一个回调函数名,实现"弹窗输入后再插入":
<?phpfunction eg_quicktags_advanced() {
if ( ! wp_script_is( 'quicktags' ) ) {
return;
}?><script>
function insert_div() {var cls = prompt( '请输入 class 名称:', '' );
if ( cls && cls !== '' ) {QTags.insertContent( '<div class="' + cls + '">\n\n</div>' );
}
}
QTags.addButton( 'my_div', 'div', insert_div, '', '', '带 class 的 div', 220 );
</script>
<?php}add_action( 'admin_print_footer_scripts', 'eg_quicktags_advanced', 11 );
回调里用 QTags.insertContent() 把内容插到光标处。
八、避坑清单
access_key早已废弃。老教程里常见第 5 个参数填'q'、'p'之类,现在完全不生效;老代码里如果塞了多字符(如'js'、'img')更是错的。留空,把提示文字挪到第 6 个参数。priority别漏。不填的话按钮会全挤在工具栏末尾、顺序还不确定,体验很差。- 只在「文本」模式可见。可视化模式下看不到是正常的,不是没生效。
- PHP 字符串里的
\n。想让插入的标签带换行,在单引号 PHP 字符串里写\n会被 JS 正确解析成换行;注意别写成 PHP 会转义的双引号形式。 - 内联 JS 里的引号冲突。标签属性用双引号时,JS 字符串用单引号包裹,反之亦然,避免提前闭合。
- 主题更新会覆盖。代码写在父主题
functions.php的话,主题一升级全没了。用子主题,或者做成wp-content/mu-plugins/下的小插件。 - 改完没反应先清缓存。浏览器缓存、对象缓存都可能让后台脚本停在旧版本,Ctrl+F5 强制刷新一次。
九、小结
- Quicktags 只作用于经典编辑器的文本模式,Gutenberg 下无效;
- WP 6.0 后按钮失效的根因是脚本加载顺序变化,修复方法是把
add_action优先级改成 11,或改用wp_add_inline_script; - 加
wp_script_is( 'quicktags' )判断,避免在无编辑器的后台页面报错; - 第 5 个参数
access_key已废弃,第 7 个参数priority决定排位,别漏。
把按钮组配好之后,写技术文章时插代码块就变成一次点击的事,长期下来省的时间相当可观。