本文约 4,435 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:同一套主题,繁体版字体发虚还有方块字
做面向港澳台或海外华人的站点时,繁体版本的显示问题很典型:正文字体在 Windows 上发虚、部分字显示为方框(缺字)、标点位置奇怪、页脚的「关于我们」还是简体中文。更隐蔽的是后台上传的繁体内容存进数据库后,个别生僻字变成问号。
这些问题分属四条不同的线:locale 判定(站点到底认为自己在用哪种语言)、主题翻译加载(界面文案有没有对应语言包)、字体栈配置(浏览器拿什么字形去渲染)、数据库字符集(能不能完整存下这些字)。四条线任意一条没接通,表现都是「显示不对」,但排查方向完全不同。本文按这四条线逐项说明,并给出可以直接跑的检查命令。
原理分析:四条线各自管什么
第一条线是 locale。 WordPress 用 get_locale() 返回当前语言标识,简体是 zh_CN,繁体(台湾)是 zh_TW,繁体(香港)是 zh_HK。主题里的界面文案(如「阅读全文」「上一篇」)要显示成繁体,必须有对应的编译后的 .mo 文件,且主题要用 load_theme_textdomain() 声明文本域与语言目录。
第二条线是字体。 浏览器按 CSS font-family 的优先级逐个尝试,第一个缺少某字的字体会自动回退到下一个。中文站点常见的问题是字体栈里只写了「Microsoft YaHei」「PingFang SC」这类简体字体,繁体字形(如「臺」「體」)在其中不存在或不完整,浏览器回退到系统默认衬线字体,观感立刻变差,极端情况缺字显示为方框。
第三条线是编码。 数据库与连接字符集必须是 utf8mb4 而非 utf8。MySQL 的 utf8 只支持最多三个字节,遇到四字节字符(部分生僻汉字、emoji)会被截断或替换为问号。WordPress 从 4.2 起默认使用 utf8mb4。
第四条线是内容本身。 界面文案靠语言包,正文内容靠人工或工具转换。二者互不替代——装了 zh_TW 语言包不会把你写的简体正文自动变成繁体。
| 环节 | 检查项 | 正确值 |
|---|---|---|
| locale | get_locale() |
zh_CN / zh_TW / zh_HK |
| 主题翻译 | 语言目录 .mo 文件 |
languages/zh_TW.mo |
| 文本域 | load_theme_textdomain() |
与 style.css 的 Text Domain 一致 |
| 字体栈 | font-family |
同时含简繁字体与后备 |
| 数据库 | DB_CHARSET |
utf8mb4 |
| 数据表 | DEFAULT CHARSET |
utf8mb4 |
多语言站点通常还会配合 WordPress 多语言插件选型 来做语言切换,本文只处理「同一站点以繁体为主要语言」的场景。
保姆级实操
- 确认 locale:后台「设置 → 常规 → 站点语言」选择「繁體中文(台灣)」或「繁體中文(香港)」,保存后用
wp option get WPLANG复核。多语言站点则由插件按语言切换。 - 准备主题语言包:在主题下建
languages/目录,放入zh_TW.mo/zh_TW.po(文件名即 locale)。用 Poedit 编辑,或用 Loco Translate 插件在后台直接翻译并保存到主题目录。 - 声明文本域加载:在
after_setup_theme里调用load_theme_textdomain(),第一个参数必须与style.css里的Text Domain完全一致,否则翻译不生效。 - 配置字体栈:CSS 里同时列出繁体优先字形(如
Noto Sans TC、PingFang TC、Microsoft JhengHei)与简体字形,最后给通用sans-serif兜底。字体文件若自托管,务必包含常用字集,缺字会显示方框。 - 核对数据库字符集:检查
wp-config.php的DB_CHARSET与数据表的DEFAULT CHARSET,不是utf8mb4就要转换。转换前必须备份。 - 验证:切到繁体环境后,检查界面文案、正文生僻字、以及后台新录入的一条含四字节字符的内容能否正常回显。
<?php
// 子主题 functions.php:加载主题翻译
add_action( 'after_setup_theme', function() {
// 文本域必须与 style.css 里的 Text Domain 一致
load_theme_textdomain( 'mimangfei', get_stylesheet_directory() . '/languages' );
} );
// 按 locale 输出一个 body 类,便于写针对性样式
add_filter( 'body_class', function( $classes ) {
$classes[] = 'locale-' . sanitize_html_class( get_locale() );
return $classes;
} );
<?php
// 只在繁体环境下加载繁体字体(避免简体站多下一份字体)
add_action( 'wp_enqueue_scripts', function() {
$locale = get_locale();
if ( in_array( $locale, array( 'zh_TW', 'zh_HK' ), true ) ) {
wp_enqueue_style(
'mimangfei-font-tc',
get_stylesheet_directory_uri() . '/assets/css/font-tc.css',
array(),
'1.0.0'
);
}
} );
/* assets/css/font-tc.css:繁体优先的字体栈 */
@font-face {
font-family: 'Noto Sans TC';
src: url('../fonts/noto-sans-tc-regular.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}
:root {
/* 繁体字形在前,简体字形兜底,最后给通用族 */
--font-zh-tc: 'Noto Sans TC', 'PingFang TC', 'Microsoft JhengHei',
'PingFang SC', 'Microsoft YaHei', sans-serif;
}
body {
font-family: var(--font-zh-tc);
line-height: 1.8; /* 中文正文行高建议不低于 1.7 */
letter-spacing: 0.02em;
}
/* 混排的拉丁文字与数字用单独的字体,避免中文标点和西文间距粘连 */
.latin, code, .entry-meta time {
font-family: 'Inter', system-ui, sans-serif;
}
-- 检查当前字符集
SELECT @@character_set_database, @@collation_database;
-- 查看某张表的字符集
SHOW TABLE STATUS WHERE Name = 'wp_posts';
-- 转换(操作前务必备份数据库)
ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_postmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 检查 wp-config.php 的字符集定义
grep -E "DB_CHARSET|DB_COLLATE" wp-config.php
# 确认语言包文件存在
ls -1 wp-content/themes/your-theme/languages/
# WP-CLI 查看与设置语言
wp option get WPLANG
wp language theme list mimangfei --all
常见踩坑
- 文本域不一致:
style.css写mimangfei,代码里写mimangfei-theme,翻译文件永远不加载。二者必须逐字符相同。 .po文件没编译成.mo:WordPress 只读取编译后的.mo,上传.po无效。- 语言包文件名写错:必须是
zh_TW.mo,写成zh-TW.mo或zh_tw.mo都不会被识别。 - 字体栈只有简体字体:繁体缺字回退,观感发虚或出现方框。这是繁体站点最常见的观感问题。
- 数据库是
utf8而非utf8mb4:生僻字和 emoji 存成问号,且这种损坏不可逆,只能回到备份或重新录入。 - 案例:一个面向台湾的教育站点上线后,用户反映课程标题里的「臺」显示为方框,页脚文案仍是简体。排查发现:字体栈里只有
PingFang SC和Microsoft YaHei,缺少繁体字形;主题的Text Domain是edu-theme,而load_theme_textdomain()写的是edu,少了一个后缀导致zh_TW.mo从未加载。两处都改掉后显示正常。这类问题的共同点是:每个环节单独看都对,拼起来才出错。 - 用机器转换正文出现用词错误:简转繁存在「一简对多繁」的问题(如「发」对应「發/髮」),专业内容建议人工校对,不能只靠转换工具。
总结
繁简显示问题的排查顺序固定为:locale 是否正确 → 语言包文件名与文本域是否匹配 → 字体栈是否含繁体字形 → 数据库字符集是否为 utf8mb4。判断标准:界面文案没变繁体查语言包,正文字形不对查字体栈,生僻字变问号查字符集。需要注意界面翻译与正文内容是两回事,装语言包不会自动转换正文。若站点同时提供多语言版本,语言切换与 URL 结构请配合主题的多语言能力一起规划,相关布局适配可参考 主题多语言与 RTL 适配。
