WordPress 文章代码高插件WP‑GeSHi‑Highlight标签用法、参数详解与易语言自定义语

如果你在 WordPress 文章里写过 <pre lang="lua" line="1" escaped="true"> 这样的标签,又在后台插件列表里翻来覆去找不着"代码高亮"插件,那这篇文章就是为你写的。

本文讲清楚四件事:这套标签到底是谁定义的、三个参数各自管什么、怎么给 GeSHi 增加一门它原本不认识的语言(以易语言为例),以及插件在 2025 年下架之后还能不能继续放心用。

一、这套标签不是 WordPress 原生能力

先给一个明确结论:WordPress 核心从来不做代码高亮。

核心挂在 the_content 上的默认过滤器,只有 wptexturize、wpautop、do_blocks、wp_filter_content_tags 这些,没有任何一个环节会去识别代码、给关键字上色。你在前台看到的彩色代码,一定是某个插件或主题在替你干。

那么 lang、line、escaped 这三个属性是哪来的?它们是 GeSHi 系高亮插件自定义的"方言"。GeSHi(Generic Syntax Highlighter)是一个老牌 PHP 语法高亮引擎,phpBB、DokuWiki、MediaWiki 都用过它。下面这三个 WordPress 插件同宗同源,都吃这套写法:

插件 说明
WP-Syntax 最早把 GeSHi 带进 WordPress 的插件,已多年未更新
WP-GeSHi-Highlight 对 WP-Syntax 的重写改进版,参数完全兼容,输出更简洁
Flyn Syntax 另一个分支,额外支持 Gutenberg 区块

二、三个参数逐个说清

1. lang —— 语言名

唯一必需的参数,取值必须是 GeSHi 语言文件的文件名(不含 .php)。常用值如下:

你想高亮 lang 该写 备注
PHP php 纯 PHP 片段;含 HTML 混排用 php-brief 效果一般
JavaScript javascript 建议全小写,大写多数版本也能识别
HTML html4strict 坑点:写 lang="html" 部分版本不识别,改用 html4strict 或 html5
CSS css —
C# csharp 不能写 C#,# 是非法字符会被过滤掉
Lua lua —
Python python —
SQL sql —
Bash / Shell bash —
纯文本(不着色) text 只想保留等宽和换行时用

2. line —— 起始行号

line="1" 表示显示行号、从第 1 行开始编号。写 line="18" 就从 18 开始。整个属性去掉,则不显示行号。

3. escaped —— 最容易踩坑的一个

这个参数的含义是:告诉插件"我存的这段代码已经被 HTML 实体转义过了,你先反转义再着色"。加上它,插件会对内容执行一次 htmlspecialchars_decode()。

为什么需要它?因为 WordPress 的可视化编辑器会偷偷帮你转义。举个完整例子:

你存进数据库的 标签写法 访客最终看到的
&lt;div&gt;(实体) escaped="true" <div> ✅ 正确
&lt;div&gt;(实体) 不加 escaped &lt;div&gt; ❌ 显示成字面实体
<div>(裸代码) 不加 escaped <div> ✅ 正确

看起来"裸代码不加 escaped"也行,但问题是:只要你切过一次可视化模式,TinyMCE 就会把裸代码里的 < 转成 &lt; 存起来,此时再不加 escaped,前台就会显示成一堆 &lt;div&gt;。

三、怎么知道你的站是谁在着色

如果你接手了一个旧站、或者忘了自己装过什么,最快的方法是看前台 HTML 的"指纹":打开一篇有代码块的文章,F12 审查元素,对照下表:

看到的包裹结构 着色引擎
wp-geshi-highlight-wrap5 → wp-geshi-highlight → div.lua → pre.de1 GeSHi(WP-GeSHi-Highlight / WP-Syntax)
pre.language-lua + code.language-lua + span.token Prism.js
code.hljs + span.hljs-keyword highlight.js
pre.EnlighterJSRAW + data-enlighter-language Enlighter
pre.wp-block-code,里面没有任何彩色 span 没人在着色,只是等宽字体 + 底色

看到 de1、kw1、st0 这类类名,就是 GeSHi 没跑了——这是它独有的 CSS class 体系。

想进一步定位代码在哪,可以在服务器上搜关键字(Windows 用 findstr,Linux 用 grep -r):

  1. cd wp-content
  2. findstr /s /i /m "geshi" *.php
  3. findstr /s /i /m "geshi" *.css

或者更简单:前台右键"查看网页源代码",搜 geshi,找到那条 <link> 样式表引用,URL 里的目录名就是答案——含 /themes/ 说明是主题内置,含 /plugins/ 说明是插件。

四、易语言怎么办:给 GeSHi 加一门语言

GeSHi 支持 200 多种语言,但没有易语言。好在它是插件式架构,加一门语言只需要往语言目录丢一个 PHP 文件。

第 1 步:找到语言目录

注意是双层 geshi 目录,这是 GeSHi 库的标准结构:

wp-content/plugins/wp-geshi-highlight/geshi/geshi/
    ├── php.php
    ├── lua.php
    ├── csharp.php
    ├── javascript.php
    └── epl.php        ← 我们要加的就是它

第 2 步:写语言定义文件

文件名决定 lang 的值:epl.php 对应 lang="epl"。下面是精简版骨架(真实文件的关键字表会长得多):

  1. <?php
  2. $language_data = array (
  3.  
  4.     'LANG_NAME' => 'Easy Programming Language',
  5.  
  6.     // 易语言行注释:单引号 + 全角 ※
  7.     'COMMENT_SINGLE' => array( 1 => "'", 2 => '※' ),
  8.     'COMMENT_MULTI' => array(),
  9.  
  10.     'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
  11.  
  12.     'QUOTEMARKS' => array( '"', '“', '”' ),
  13.     'ESCAPE_CHAR' => '',
  14.  
  15.     'KEYWORDS' => array(
  16.         // 1 组:数据类型与结构
  17.         1 => array( '双精度小数型', '整数型', '文本型', '逻辑型', '字节集',
  18.                     '子程序', '程序集', '返回值', '参数', '变量' ),
  19.         // 2 组:流程控制(注意:长关键字必须排在短关键字前面)
  20.         2 => array( '判断循环', '计次循环', '如果真', '循环', '判断',
  21.                     '如果', '否则', '返回', '结束' ),
  22.         // 3 组:常用命令
  23.         3 => array( '信息框', '到文本', '到数值', '取文本长度', '分割文本',
  24.                     '读入文件', '写到文件', '调试输出' ),
  25.     ),
  26.  
  27.     'CASE_SENSITIVE' => array( GESHI_COMMENTS => false, 1 => false,
  28.                                2 => false, 3 => false ),
  29.  
  30.     'STYLES' => array(
  31.         'KEYWORDS' => array(
  32.             1 => 'color: #0000ff; font-weight: bold;',  // 类型:蓝色加粗
  33.             2 => 'color: #af00db; font-weight: bold;',  // 流程:紫色加粗
  34.             3 => 'color: #267f99;',                     // 命令:青色
  35.         ),
  36.         'COMMENTS' => array( 1 => 'color: #008000; font-style: italic;',
  37.                              2 => 'color: #008000; font-style: italic;' ),
  38.         'STRINGS'  => array( 0 => 'color: #a31515;' ),
  39.         'NUMBERS'  => array( 0 => 'color: #098658;' ),
  40.     ),
  41.  
  42.     'URLS'   => array( 1 => '', 2 => '', 3 => '' ),
  43.     'OOLANG' => false,
  44.     'REGEXPS'=> array(),
  45.     'STRICT_MODE_APPLIES' => GESHI_NEVER,
  46.     'SCRIPT_DELIMITERS'   => array(),
  47.     'TAB_WIDTH' => 4,
  48. );

第 3 步:三个必踩的坑

① 文件名必须等于 lang 的值。 epl.php ↔ lang="epl",写错一个字母就是纯文本。

② 长关键字必须排在短关键字前面。 这是最容易忽略的一条。GeSHi 用正则顺序匹配,如果"如果"排在"如果真"前面,那么源码里的"如果真"会被切成"如果"+"真"两段。同理"整数型"要排在"长整数型"之后。

③ 文件必须是 UTF-8 无 BOM。 用记事本另存会加 BOM,导致 PHP 报 Cannot modify header information 或语言文件加载失败。用 VS Code / Notepad++ 保存时显式选择"UTF-8 无 BOM"。

第 4 步:清缓存再验证

装了页面缓存(Redis、WP Rocket 等)的站,前台很可能还挂着旧 HTML。清一次全站缓存,再发一段测试代码:

  1. .版本 2
  2. .子程序 _启动子程序, 整数型
  3.     信息框 ("你好,易语言", 0, )  ' 这是一行注释
  4.     返回 (0)

中文关键字变蓝变紫即成功;整块是纯文本,回去检查文件名和目录层级。

五、插件 2025 年下架了,还能用吗

事实部分

  • WP-GeSHi-Highlight 于 2025 年 3 月 18 日被 WordPress.org 关闭,原因是 Security Issue,官方页面已无法下载;
  • 最后一个版本是 1.4.3(2023 年 4 月发布),此后不再更新;
  • 对应漏洞编号 CVE-2024-13896,类型是正则回溯导致的拒绝服务(ReDoS),CVSS 6.5;
  • 触发条件是"拥有作者及以上权限的账号提交恶意构造的代码块内容";
  • 底层的 GeSHi 引擎自 2019 年起就已停止维护。

怎么判断自己要不要换

你的情况 建议
单管理员、不开放投稿 继续用没问题。能提交内容的人只有你自己,漏洞的攻击面不存在
多作者、开放注册、接受投稿 应该换了。任何一个作者账号都能触发
站点对可用性要求高(怕被打挂) 建议换

真要换,怎么做到老文章零改动

关键思路:既然数据库里存的是原始标签,那就在 the_content 上挂一个过滤器,把这套老标签在输出时就地翻译成新库能识别的结构。以迁移到 Prism.js 为例:

  1. <?php
  2. add_filter( 'the_content', function ( $content ) {
  3.     if ( stripos( $content, '<pre' ) === false ) return $content;
  4.  
  5.     return preg_replace_callback( '#<pre\b([^>]*)>(.*?)</pre>#si', function ( $m ) {
  6.         $attrs = $m[1];
  7.         $code  = $m[2];
  8.  
  9.         if ( ! preg_match( '/\blang\s*=\s*["\']([^"\']+)["\']/i', $attrs, $lm ) ) {
  10.             return $m[0];
  11.         }
  12.         $lang  = strtolower( trim( $lm[1] ) );
  13.         $alias = array( 'js' => 'javascript', 'html' => 'markup',
  14.                         'html4strict' => 'markup', 'php-brief' => 'php',
  15.                         'shell' => 'bash', 'py' => 'python' );
  16.         $lang  = isset( $alias[$lang] ) ? $alias[$lang] : $lang;
  17.  
  18.         if ( ! preg_match( '/\bescaped\s*=\s*["\']true["\']/i', $attrs ) ) {
  19.             $code = htmlspecialchars( $code, ENT_NOQUOTES, 'UTF-8' );
  20.         }
  21.  
  22.         $class = 'language-' . $lang;
  23.         if ( preg_match( '/\bline\s*=\s*["\'](\d+)["\']/i', $attrs, $sm ) ) {
  24.             $class .= ' line-numbers';
  25.         }
  26.         return sprintf( '<pre class="%1$s"><code class="language-%2$s">%3$s</code></pre>',
  27.             esc_attr( $class ), esc_attr( $lang ), $code );
  28.     }, $content );
  29. }, 9 );

几个注意点:优先级必须是 9 或更早,否则 wpautop(优先级 10)会先把换行变成 <br>;切换前记得停用 GeSHi 插件,两套过滤器会互相抢标签;国内站点建议自托管 Prism,别直接用公共 CDN。

六、换个配色:自定义 CSS

插件自带一个 wp-geshi-highlight.css。想改样式,不要直接改插件目录里的文件(更新会覆盖),而是:

  1. 把 wp-geshi-highlight.css 复制到当前主题根目录;
  2. 改这个文件——插件发现主题目录里有同名文件,会优先加载主题里的版本;
  3. 这样即使插件更新,你的自定义样式也不会丢。

常用调整片段:

  1. /* 代码块整体:字号、行高、圆角 */
  2. .wp-geshi-highlight pre {
  3.     font-size: 14px;
  4.     line-height: 1.6;
  5.     border-radius: 4px;
  6.     padding: 12px 15px;
  7. }
  8.  
  9. /* 允许横向滚动,长代码不撑破布局 */
  10. .wp-geshi-highlight {
  11.     overflow-x: auto;
  12. }
  13.  
  14. /* 行号列颜色调淡一点 */
  15. .wp-geshi-highlight .de1,
  16. .wp-geshi-highlight .li1 { color: #333; }

七、小结

  • <pre lang="xxx"> 是 GeSHi 系插件的私有方言,WordPress 核心不认识它;
  • 三个参数:lang 是语言文件名、line 管行号起始、escaped="true" 表示内容已转义需先反转义;
  • 语言名有坑:C# 写 csharp,HTML 建议写 html4strict;
  • 加自定义语言 = 往 geshi/geshi/ 丢一个以语言命名的 PHP 文件,注意长关键字排前面;
  • 插件虽已下架且带 ReDoS,但单管理员站点可继续放心使用,服务端渲染反而是性能最优的方案。

如果你也在用易语言写自动化脚本、又习惯用 WordPress 记笔记,希望这篇能帮你把代码块的显示彻底理顺。


发布日期:

所属分类: WordPress 插件 标签:



下一篇:

没有了,已经是最新文章