如何在 WordPress .po 文件中修复模糊翻译

你翻译了所有的字符串。你保存了文件,上传了 .mo 文件,并刷新了你的网站。然而,一些标签仍然顽固地显示为英文。你打开 .po 文件,找到了那个字符串,它就在那里,翻译得完美无缺。那么,为什么 WordPress 会忽略它呢?
答案几乎总是一个隐藏在条目上方的小标记:#, fuzzy。模糊翻译是 gettext 表示“此翻译可能不正确,因此暂时不要相信它”的方式。关键是,WordPress 拒绝在实时网站上显示模糊字符串,而是回退到原始英文。这是“我的翻译没有显示”问题最常被误解的原因之一。
本指南将详细解释模糊翻译标记的含义、为什么它会不断出现在你的目录中,以及如何在 Poedit、命令行中以及在整个待办事项列表中大规模查找和清除模糊字符串。一旦你理解了其机制,翻译缺失的谜团就会迎刃而解。
模糊标记到底意味着什么?
模糊标记是 gettext 添加到翻译条目中的一个标记,表示该翻译不确定且需要人工审核。在原始的 .po 文件中,它以特殊注释的形式直接出现在字符串上方。
#: includes/cart.php:88
#, fuzzy
msgid "Add to cart"
msgstr "Im Warenkorb"
这条 #, fuzzy 行告诉所有支持 gettext 的工具(包括 WordPress),其下方的 msgstr 是暂定的。翻译存在,但 gettext 认为它尚未确认。
为什么 WordPress 会跳过模糊字符串
这就是让所有人措手不及的行为。当 WordPress 编译或读取 .mo 文件时,它会将模糊条目视为未翻译。该字符串技术上存在于文件中,但 WordPress 会故意忽略它,并显示原始的 msgid。
因此,从你的角度来看,翻译“完成了”,它就在文件中。但从 WordPress 的角度来看,该字符串没有可信的翻译,因此它会渲染英文原文。这正是为什么一个看起来已经完成的目录仍然会在前端显示未翻译文本的原因。
这种设计是有意的,而且公平地说,是合理的。模糊标记的全部意义在于防止未经验证、可能错误的翻译在不知不觉中上线。想象一下,一个字符串最初显示为“Delete account”(删除账户),后来改为“Deactivate account”(停用账户)。如果 gettext 盲目地保留旧翻译,你的用户可能会看到一个标有“Delete account”的按钮,而它实际上只是停用,这是一个危险的不匹配。通过隐藏模糊字符串,gettext 强制人工确认翻译仍然与新含义匹配,然后才将其推送给任何人。这个标记是一种安全机制,而不是一个错误。
为什么模糊标记会不断出现?
模糊标记并非随机出现。它们主要在两种情况下由 gettext 工具自动生成,了解这两种情况能帮助你预防它们。
源字符串已更改
最常见的原因是源文件更新。想象一下,开发者在下一个插件版本中将一个字符串从“Add to cart”更改为“Add to basket”。当你将新模板合并到现有翻译中时,gettext 会发现源文件不再与你最初翻译的内容匹配。它不会丢弃你的旧翻译,而是保留它并将其标记为模糊,本质上是说:“英文原文已更改,请重新检查你的翻译是否仍然适用。”
翻译记忆和 msgmerge 的自动匹配
第二个原因是合并过程中的模糊匹配。msgmerge 工具会根据新模板更新旧的翻译文件,当它找到一个与之前某个源字符串相似但不完全相同的字符串时,它会复制旧翻译并将其标记为模糊。
# Merge a new template into an existing translation.
# Similar-but-changed strings get marked #, fuzzy automatically.
msgmerge --update awesome-plugin-de_DE.po awesome-plugin.pot
桌面编辑器中的翻译记忆库行为相同:当它从近似匹配中自动填充建议时,它会将结果标记为模糊,以便你记住进行验证。在这两种情况下,标记都在发挥其作用。问题仅仅在于模糊条目未经审核,而 WordPress 会悄悄地将其隐藏。
还有第三个,更隐蔽的来源值得了解:复制粘贴和批量导入工具。一些翻译平台和导入脚本默认将每个条目标记为模糊,作为一种保守措施,期望人工在之后确认每一个。如果你从另一个系统导入目录,发现每个字符串都突然变成模糊的,这通常就是原因。翻译可能完全没问题,但在清除标记之前,它们都不会显示在你的网站上。了解这些标记的来源可以告诉你是否真的需要审核每个条目,或者批量清除是否安全可靠。
如何查找和修复模糊字符串?
清除模糊字符串意味着审核每一个字符串,一旦确认翻译正确,就移除标记。根据任务的大小,有三种实用的方法可以做到这一点。
在 Poedit 中修复模糊字符串
Poedit 让这变得非常简单。打开 .po 文件,使用搜索和筛选控件只显示模糊条目,它们通常会用颜色(通常是橙色)编码,因此会立即突出显示。点击每个条目,确认或更正翻译,然后使用键盘快捷键(“编辑”然后是“Translation is Fuzzy”,或菜单中显示的快捷键)关闭模糊状态。保存后,Poedit 会重新编译一个干净的 .mo 文件,然后这些已确认的字符串就会显示在你的网站上。如果你是该编辑器的初学者,完整的 Poedit 指南详细介绍了筛选和审核工作流程。
在命令行中修复模糊字符串
对于自动化或大型目录,命令行会更快。你可以统计模糊条目,并在批量验证后,剥离这些标记,以便 WordPress 能够加载它们。
# Count how many fuzzy strings remain
msgattrib --only-fuzzy --no-obsolete awesome-plugin-de_DE.po | grep -c "msgid"
# Clear all fuzzy flags (only after you trust the translations)
msgattrib --clear-fuzzy --empty awesome-plugin-de_DE.po \
--output-file=awesome-plugin-de_DE.po
批量清除时请务必小心。在不审核翻译的情况下移除模糊标记会违背该标记的初衷,并可能向你的用户提供真正错误的文本。当你信任翻译来源时,使用命令行方法;当你怀疑时,则采用手动 Poedit 方式。
一个安全的折衷方案是将模糊字符串导出到单独的文件中,只审核这些,然后再合并回来。这可以在你只关注需要注意的条目时,保持你已确认的翻译不受影响。
# Extract only the fuzzy entries for focused review
msgattrib --only-fuzzy --no-obsolete awesome-plugin-de_DE.po \
--output-file=fuzzy-only.po
审核五十个独立的字符串比滚动一千行的目录寻找橙色行要不容易出错得多,而且它能为你提供上次更新中确切更改内容的清晰记录。
清除标记后,务必重新保存或重新编译 .mo 文件。模糊状态存在于 .po 文件中,但 WordPress 读取的是二进制的 .mo 文件,因此在你重新生成它之前,即使 .po 文件看起来很干净,你的前端仍会显示英文。Poedit 会在保存时自动重新编译;在命令行中,你运行 msgfmt awesome-plugin-de_DE.po -o awesome-plugin-de_DE.mo。忘记这最后的编译步骤是导致新清除模糊标记的目录仍未显示的最常见原因之一,翻译在源文件中已确认,但网站实际加载的二进制文件已过时。
请注意,模糊条目通常会与复数字符串一起出现,其中更改的 msgid_plural 会将整个复数块标记为模糊。如果你的模糊待办事项中包含大量计数和数量,我们关于 Gettext 复数和复杂复数形式的指南解释了为什么这些条目在合并过程中特别脆弱。
大规模清除模糊待办事项
一个模糊字符串只需三十秒就能修复。在一个主要插件更新后,包含四百个模糊字符串的目录则是一个不同的问题,如果涉及十几种语言,它会成为一个真正的瓶颈。未经审核就批量清除标记的诱惑,正是导致损坏翻译进入生产环境的原因。
一个更简洁的解决方案是重新翻译模糊条目,而不是草率地批准过时的匹配项。当你通过 SimplePoTranslate 处理目录时,上下文感知 AI 会为每个更改的字符串生成当前、已确认的翻译,这样你不仅移除了警告标记,还用真实的翻译替换了不确定的匹配项。语法锁定在处理过程中会确保每个 %s、%1$s、{count} 和 HTML 标签完好无损,而智能批量处理可以一次性处理大型更新后的目录。你将获得一个干净的 ZIP 文件,其中包含 .po、.mo、.json、.php 和 .xliff 文件,没有遗留的模糊待办事项,可以随时从云端部署。
值得将此与更广泛的“为什么翻译根本不显示”问题区分开来。模糊标记是一个具体原因,但 .mo 文件缺失、文件名错误和区域设置不匹配也会导致相同的症状。有关完整的诊断清单,请参阅我们的 WordPress 翻译不显示故障排除指南,该指南将模糊字符串视为其中一项。
准备好清除所有模糊待办事项并让所有字符串都显示在你的网站上吗?免费试用 SimplePoTranslate —— 无需信用卡。免费套餐会全新重新翻译你的 .po 文件,用干净、已确认的翻译替换不确定的模糊匹配项。