搜索全站
主题 12 分钟阅读

繁体中文与简体的显示处理:主题字体、语言包与编码设置

面向港澳台用户的站点字体发虚、部分字显示为方块?本文讲清 locale 判定、主题翻译加载、字体栈配置与数据库字符集四条线,给出可直接落地的配置与检查命令。

U
UFO_PF 2018-08-03 · 阅读 12 分钟
繁体 主题
阅读提示
本文约 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 多语言插件选型 来做语言切换,本文只处理「同一站点以繁体为主要语言」的场景。

保姆级实操

  1. 确认 locale:后台「设置 → 常规 → 站点语言」选择「繁體中文(台灣)」或「繁體中文(香港)」,保存后用 wp option get WPLANG 复核。多语言站点则由插件按语言切换。
  2. 准备主题语言包:在主题下建 languages/ 目录,放入 zh_TW.mo / zh_TW.po(文件名即 locale)。用 Poedit 编辑,或用 Loco Translate 插件在后台直接翻译并保存到主题目录。
  3. 声明文本域加载:在 after_setup_theme 里调用 load_theme_textdomain(),第一个参数必须与 style.css 里的 Text Domain 完全一致,否则翻译不生效。
  4. 配置字体栈:CSS 里同时列出繁体优先字形(如 Noto Sans TC、PingFang TC、Microsoft JhengHei)与简体字形,最后给通用 sans-serif 兜底。字体文件若自托管,务必包含常用字集,缺字会显示方框。
  5. 核对数据库字符集:检查 wp-config.php 的 DB_CHARSET 与数据表的 DEFAULT CHARSET,不是 utf8mb4 就要转换。转换前必须备份。
  6. 验证:切到繁体环境后,检查界面文案、正文生僻字、以及后台新录入的一条含四字节字符的内容能否正常回显。
<?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 适配。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。