如何为主题或插件创建 .pot 文件

你刚刚完成了一个想与全世界分享的 WordPress 插件。代码运行良好,功能稳定,然后德国有人发邮件询问如何将其翻译成德语。你指给他们 languages 文件夹,却发现里面空空如也。没有模板,没有字符串,翻译人员甚至不知道什么需要翻译。你的插件在技术上只是“翻译就绪”而已,徒有虚名。
每个可翻译的 WordPress 项目都始于一个文件:.pot 模板。在任何人能够生成德语、法语或日语版本之前,你必须创建一个 POT 文件,列出代码中所有面向用户的字符串。跳过这一步,翻译人员就只能逐行阅读你的源代码,猜测哪些字符串是可见的。
本指南将介绍这项工作的两个部分:准备源代码以便字符串可被发现,然后使用三种不同的工具生成 .pot 文件本身。我们将使用 WP-CLI、Poedit 和传统的 makepot/grunt 方法,并提供你可以复制的实际命令。到最后,你将拥有一个可随时交付给任何翻译人员的干净模板。
第一步:将你的字符串标记为可翻译
在创建 POT 文件之前,用户可能看到的每个字符串都需要用 Gettext 函数包裹起来。扫描器只能提取它识别的字符串,并通过这些函数调用来识别它们 — 纯字符串字面量对它来说是不可见的。
WordPress 提供了一系列本地化函数,每个函数适用于略微不同的上下文:
// Return a translated string
$label = __( 'Add to Cart', 'my-plugin' );
// Echo a translated string directly
_e( 'Your cart is empty', 'my-plugin' );
// Translate with context to disambiguate identical words
$verb = _x( 'Post', 'verb: to publish', 'my-plugin' );
// Translate AND escape for safe HTML output
echo esc_html__( 'Welcome back', 'my-plugin' );
每个调用中的第二个参数 — 'my-plugin' — 是文本域。它将插件或主题的所有字符串归入一个命名空间,这样 WordPress 就知道为它们加载哪个 .mo 文件。项目中的每个可翻译字符串都必须共享完全相同的文本域,否则有些字符串将永远无法被翻译。
当一个词语有歧义时,请使用 _x()。英文的“Post”可以是名词也可以是动词,许多语言的翻译方式不同。上下文字符串可以让翻译人员区分它们。当翻译后的字符串打印到 HTML 中时,请使用 esc_html__() 和 esc_attr__() 变体,这样可以同时确保安全和本地化。
有一些习惯可以保持你的字符串可提取。始终将纯字符串字面量作为第一个参数传递 — 绝不能是变量或像 __( 'Hello ' . $name, 'my-plugin' ) 这样的拼接,因为扫描器静态读取源代码,无法解析运行时值。对于带有数字的句子,使用 _n() 以正确捕获复数形式;对于带有动态值的句子,使用 sprintf() 围绕占位符(例如 %s),而不是将字符串拼接在一起。这里的 axons 保持一致性是使下一步 — 生成模板 — 产生完整可用结果的关键。
第二步:在你的头部声明文本域
WordPress 需要两个头部字段来知道你的翻译文件在哪里:文本域和域路径。在插件的主文件或主题的 style.css 中设置它们,WordPress 将在运行时自动加载正确的 .mo 文件。
<?php
/**
* Plugin Name: My Plugin
* Description: A perfectly localized WordPress plugin.
* Version: 1.0.0
* Requires at least: 6.4
* Text Domain: my-plugin
* Domain Path: /languages
*/
文本域必须与你传递给每个 __() 和 _e() 调用的字符串 — 此处的 my-plugin — 匹配。域路径告诉 WordPress 哪个子文件夹存放翻译文件,它是相对于插件或主题根目录的。约定是 /languages,这正是你生成的 .pot 文件应该存放的位置。
字符串包裹完成,头部声明完毕,你的代码已准备好进行扫描。准备项目进行翻译的更广泛内容 — 包括非你自己的主题 — 在即使你不是开发者,如何本地化任何 WordPress 主题中有所涵盖。
如何生成 .pot 文件?三种方法
你通过对源代码运行扫描器来生成 .pot 文件,该扫描器会找到每个 Gettext 调用并将字符串写入模板。以下是三种可靠的方法,从现代默认方法到传统方法。
方法一:WP-CLI(推荐)
创建 POT 文件的官方、现代方式是使用带有 i18n 命令的 WP-CLI。它是 WordPress 核心工具的一部分,能够理解 PHP 和 JavaScript 字符串,并在一行命令中生成符合标准的模板。
# Run from your plugin or theme root directory
wp i18n make-pot . languages/my-plugin.pot
# Add a text domain explicitly if auto-detection misses it
wp i18n make-pot . languages/my-plugin.pot --domain=my-plugin
# Scan only specific paths and exclude vendor folders
wp i18n make-pot . languages/my-plugin.pot --exclude=vendor,node_modules
第一个参数是源目录(当前文件夹用 . 表示),第二个是输出路径。WP-CLI 会遍历你的文件,提取每个被包裹的字符串,将源文件和行号记录为注释,然后写入 .pot 文件。它速度快、可脚本化,是任何严肃项目的正确选择。
生成的模板包含有用的元数据,你可以通过额外的标志进行调整。传递 --headers 可以设置项目名称、版本和翻译人员的联系地址,这样 .pot 头部块就能正确填充,而不是留下占位符。WP-CLI 还会自动从 wp_set_script_translations() 调用中提取 JavaScript 字符串,这对于现代块主题和 Gutenberg 插件很重要,因为其中一半面向用户的文本存在于 JavaScript 而不是 PHP 中。一个命令即可覆盖这两种情况。
方法二:Poedit(图形界面)
如果你喜欢桌面应用程序,Poedit 可以通过其界面扫描你的源代码并生成模板。打开 Poedit,选择从 POT 创建新翻译或直接扫描源文件,指向你的项目文件夹,并在目录属性下配置源关键词(__、_e、_x、esc_html__)。
Poedit 的源扫描和 .pot 生成功能在其 Pro 版本中提供,但其工作流程对于那些喜欢点击而不是输入命令的开发者来说非常友好。它也是后续翻译阶段的一个可靠编辑器。Poedit 和其他几种桌面选项在Mac 和 Windows 上编辑和翻译 PO 文件的 5 大免费工具中进行了比较。
方法三:makepot / grunt(传统方法)
在 WP-CLI 之前,标准工具是来自 WordPress i18n-tools 仓库的 makepot.php 脚本,通常通过 grunt-wp-i18n 连接到 Grunt 构建任务中。在较旧的插件和主题中你仍然会遇到它。
# Legacy makepot.php invocation
php makepot.php wp-plugin /path/to/my-plugin languages/my-plugin.pot
它虽然可用,但与 WP-CLI 相比维护不足,设置也较慢。仅当你维护一个已经依赖它的传统项目时才使用它;对于任何新项目,请优先选择 wp i18n make-pot。
随着代码变更保持模板更新
.pot 文件是你字符串在某一时刻的快照。每次你添加新功能、更改标签或修复可见字符串中的错别字时,模板都会过时,翻译人员会错过新的措辞。
将重新生成作为发布流程的一部分。在每次版本升级前重新运行 wp i18n make-pot,然后使用 wp i18n update-po 或 msgmerge 将更新后的模板合并到现有翻译中,这样翻译人员可以保留他们已完成的工作,只看到新的缺失部分。将 .pot 文件视为一个可重新生成的构建工件,而不是手动编辑的文件。
过时的模板会导致一种微妙而令人沮丧的失败:即使在一个“完全翻译”的网站上,新字符串仍然以英文显示,因为它们从未出现在翻译人员使用的 .pot 文件中。发现这一点很简单,只需将重新生成脚本化到你的构建过程中,这样模板就永远不会落后于代码。一些团队会添加 CI 检查,如果重新生成 .pot 文件产生差异,则构建失败,从而保证提交的模板始终与当前源代码匹配。
一旦翻译人员返回完成的 .po 文件,这些文件仍需要编译成 WordPress 实际加载的二进制 .mo 文件 — 如果你宁愿跳过整个下载-翻译-重新编译的循环,一个云工具可以端到端地处理它。SimplePoTranslate 直接接受你的 .pot 文件,使用上下文感知 AI 进行翻译,该 AI 了解每个字符串在你的界面中的含义,并返回一个包含已经构建并命名的 .po、.mo 等文件的单个 ZIP 包。它的语法锁定功能会冻结像 %s 和 %1$s 这样的占位符,这样你的变量在翻译中永远不会损坏。
总结
要正确创建一个 POT 文件,首先要使你的代码可发现 — 将每个可见字符串用 __()、_e()、_x() 或其转义变体包裹起来,所有这些字符串共享一个文本域,并在你的头部声明该域以及 Domain Path。然后,对于新项目,使用 WP-CLI 生成模板;如果你喜欢图形界面,则使用 Poedit;仅在维护旧代码时才使用 makepot。
尽早生成,经常重新生成,永远不要让你的模板落后于代码。一个最新的 .pot 文件是一个真正为世界准备好的插件与一个仅仅声称如此的插件之间的区别。
准备好将你的
.pot模板转换为最终翻译,而无需手动编译的繁琐过程?免费试用 SimplePoTranslate — 无需信用卡。在免费套餐中上传你的模板,并在几分钟内下载即时可用的翻译文件。