WordPress: WordPress 禁用字符转义 wptexturize()
字符转义函数 wptexturize()
WordPress 内置函数 wptexturize($text)
会将文本中的特定字符进行转换,比如将横杠「-」转换成「–」,将三个横杠「---」转换成「—」,将三个点「...」转换成「…」。
但让我觉得有点烦人的就是,WordPress 默认会对几乎所有的文本进行 wptexturize 转义。可以在 wordpress/wp-includes/default-filters.php 文件中看到,WordPress 将 wptexturize()
函数注册到了很多过滤器钩子中。比如 the_content 钩子,是用来返回文章内容的,the_title 钩子,是用来返回文章标题的。
wptexturize()的智能转换有下面这些:
原始文本 | 转换之后的文本 | 符号名称 |
---|---|---|
"---" | "—" | em-dash | 破折号 |
" -- " | "—" | em-dash | 破折号 |
"--" | "–" | en-dash | 连接号 |
" - " | "–" | en-dash | 连接号 |
"..." | "…" | ellipsis | 省略号 |
"xn–" | "xn--" | |
`` | “ | opening quote | 开启引号 |
"hello | “hello | opening quote | 开启引号 |
'hello | ‘hello | opening quote | 开启引号 |
'' | ” | closing quote | 关闭引号 |
world." | world.” | closing quote | 关闭引号 |
world.' | world.’ | closing quote | 关闭引号 |
" (tm) " | " ™ " | trademark symbol | 注册商标符号 |
1234" | 1234″ | double prime symbol | 角秒符号 |
1234' | 1234′ | prime symbol | 角分符号 |
'99 | ’99 | apostrophe|缩写年份前的撇号 |
Webster's | Webster’s | apostrophe|单词中的撇号 |
1234x1234 | 1234×1234 | multiplication symbol | 乘法符号 |
禁用 wptexturize
但是实际上,我是并不希望 WordPress 对我的内容进行转义的。所以我需要想办法把 WordPress 的这个默认行为禁用掉。
1 普遍但不太安全的禁用方式 ✗
早期的禁用方式,大家普遍都是采用 remove_filter()
函数,将 wptexturize()
从过滤器钩子中去掉。我也是如此。(甚至现在用中文关键字搜索 “wordpress 字符 转义”,出来的结果还几乎都是这种方法!)
在自定义主题的 functions.php,添加如下代码:
// 取消文章内容转义 remove_filter('the_content', 'wptexturize'); // 取消文章摘要转义 remove_filter('the_excerpt', 'wptexturize'); // 取消评论转义 remove_filter('comment_text', 'wptexturize');
直到这几天换了一个“文章目录”插件 ezTOC,发现它在生成目录的时候,对于一些标题中存在特殊符号的,会无法跳转。查了半天,才发现原来是跟我禁用 wptexturize()
冲突了。
因为它在匹配标题(heading)的时候,默认会应用 wptexturize()
进行转义。
然后在生成目录时候它使用的就是转义后的文本。并且会再次匹配文章中的 heading,将 heading 加上锚点。(类似将「<h1>这是标题</h1>」转换成「<h1><span class='ezTOC' id='anchor_1'>这是标题</span></h>」这样子)
而我们文章实际输出的 heading 是取消转义的。这时候如果有一个标题里面有横杠「-」,它在最终生成标题锚点的时候就会失败。
2 更安全的禁用方式 ✓
注:实测此方法在 WordPress 6.5 版本 无效。
查看 wptexturize()
的说明文档或者源码,会发现它其实提供了 $run_texturize = apply_filters( 'run_wptexturize', $run_texturize )
这个开关来允许全局禁用 texturize。
这时候,我们只需要在自定义主题的 functions.php 文件中使用如下代码:
// 全局禁用 wptexturize 转义 // __return_false 是 WordPress 内置的一个便捷函数,直接返回 false。 add_filter('run_wptexturize', '__return_false');
这样,不论是 WordPress 还是第三方插件,在任意地方调用 wptexturize()
方法,都不会进行转义了。
3 针对特定标签禁用 wptexturize
此外,wptexturize()
函数体中还有两个钩子可以用来禁用指定的 HTML 标签和 shortcode 标签([shortcode] 是 WordPress 自己提供的标签格式,用来供给第三方插件进行自动替换的)。
禁用指定的 HTML 标签:
apply_filters( 'no_texturize_tags', string[] $default_no_texturize_tags )
禁用指定的 [shortcode] 标签:
apply_filters( 'no_texturize_shortcodes', string[] $default_no_texturize_shortcodes )
如果只想针对某些特定 HTML 标签禁用 wptexturize,那么可以在 functions.php 中使用如下代码:
add_filter( 'no_texturize_tags', 'my_no_texturzie_tags' ); function my_no_texturzie_tags( $tags ) { $tags[] = 'blockquote'; // <blockquote> 标签 $tags[] = 'h1'; // <h1> 标签 return $tags; }