EmDash 的管理后台界面支持翻译,使用 Lingui 提取消息,使用 Lunaria 跟踪翻译进度。所有翻译都存放在 PO(gettext)文件中,每个语言一个文件。
翻译状态
请查看翻译仪表板,了解所有语言的当前进度。
谁可以翻译
每一份翻译都必须由母语者或流利的使用者监督。接受 AI 生成的翻译,但前提是有流利的使用者审阅每一个字符串,并在提交前在正在运行的管理后台中预览。不接受未经监督的机器输出。请参阅下方的 AI 辅助翻译和测试你的翻译。
宁可不翻译某个字符串,也不要把它翻译错。错误的翻译会误导用户;英文回退只会给他们带来不便。
文件结构
翻译目录位于 packages/admin/src/locales/:
packages/admin/src/locales/
├── en/
│ └── messages.po # English (source)
├── de/
│ └── messages.po # German
└── ...
每个 .po 文件包含 msgid/msgstr 对。msgid 是英文源文本;msgstr 是你的翻译。msgstr 为空表示“尚未翻译”,Lingui 会在运行时回退到英文。
翻译字符串
-
查看翻译仪表板,了解哪些内容需要处理。检查未关闭的 PR,避免重复劳动。
-
Fork 仓库并创建分支:
git checkout -b i18n/de -
打开你所用语言的 PO 文件(例如
packages/admin/src/locales/de/messages.po)。 -
填写翻译。 每个条目如下所示:
#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr ""填写
msgstr:#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr "Mit Passkey anmelden" -
测试你的翻译(见下文)。
-
向
main提交 PR。 标题格式:i18n(de): add/update German translations。请将 PR 限定为 PO 文件、一个 changeset,以及添加新语言中描述的语言文件。如果翻译 PR 修改了其他任何内容,自动化机器人会留下评论。
需要翻译的内容
- 每个条目的
msgstr值。
不需要翻译的内容
msgid值,它们是查找键。- 插值占位符,如
{error}、{email}、{label},请保持原样。 - XML 风格标签,如
<0>、</0>,它们包裹交互元素(链接、按钮)。请保留标签,并翻译标签之间的文本。 - 以
#:开头的注释,它们是 Lingui 添加的源码引用。
插值和标签
某些字符串包含占位符和标签:
msgid "Authentication error: {error}"
msgstr "Authentifizierungsfehler: {error}"
msgid "Don't have an account? <0>Sign up</0>"
msgstr "Noch kein Konto? <0>Registrieren</0>"
msgid "If an account exists for <0>{email}</0>, we've sent a sign-in link."
msgstr "Falls ein Konto für <0>{email}</0> existiert, haben wir einen Anmeldelink gesendet."
占位符({error}、{email})会在运行时被替换为动态值。标签(<0>...</0>)包裹 React 组件。两者都必须在你的翻译中与源文本完全一致地出现,名称和嵌套结构都不能改变。
测试你的翻译
-
编译并运行演示:
pnpm run locale:compile pnpm build pnpm --filter emdash-demo dev -
在管理后台的设置页面中切换语言,并确认你的翻译在上下文中看起来正确。
伪语言环境
EmDash 内置了一个伪语言环境(pseudo locale),它会把所有被包裹的字符串变成带重音符号的相似字符,例如 "Dashboard" 会变成 "Ðàšĥƀöàřð"。在伪语言环境启用时,任何仍以普通英文显示的字符串,要么缺少 t\…“ 包裹,要么来自目录之外。
要启用它,请在演示目录的 .env 文件中添加以下内容:
EMDASH_PSEUDO_LOCALE=1
然后重启开发服务器。伪语言环境会以 Pseudo 的名称出现在登录页面和设置中的语言选择器里。切换到它,就能一眼发现未被包裹的字符串。
添加新语言
如果你的语言还没有 PO 文件:
-
将该语言添加到
packages/admin/src/locales/locales.ts:export const LOCALES: LocaleDefinition[] = [ { code: "en", label: "English", enabled: true }, // ... { code: "vi", label: "Tiếng Việt", enabled: false, dateLocale: () => import("react-day-picker/locale/vi").then((m) => m.vi), }, ];dateLocale会加载你所用语言的日历和日期格式本地化。请在react-day-picker/locale中选择最接近的文件,例如用pt对应pt-PT,并使用该文件中命名的导出。只有当你的语言使用美式英语日历时才可以省略它。这是唯一的事实来源:
lingui.config.ts、lunaria.config.ts和管理后台运行时都从这个文件派生语言列表。翻译进行期间请设置enabled: false。当该语言的覆盖率足以在管理后台界面中使用时,由维护者将其启用。 -
运行提取,生成空的 PO 文件:
pnpm run locale:extract这会创建
packages/admin/src/locales/{your-locale}/messages.po,其中包含所有待翻译的字符串。 -
按照上述步骤翻译并测试。
翻译标准
准确性
翻译应以母语者的水准忠实地呈现英文源文本。不要增加、删减或重新解读含义。如果源字符串有歧义,请查看 #: 注释中的源文件位置,并阅读组件代码以理解上下文。
一致性
在你的语言中使用一致的术语。如果你在某处把 “collection” 译为 “Sammlung”,就不要在别处改用 “Kollektion”。如果你的语言已有翻译,请在开始之前通读现有的 PO 文件,以匹配既定术语。
语气
管理后台界面采用直接、专业的语气。请在你的语言中保持一致,避免过于正式或过于随意的措辞。
AI 辅助翻译
你可以使用 AI 工具生成翻译,包括完整的初稿,但必须由流利的使用者监督结果:
- 流利的使用者必须审阅每一个字符串。AI 工具会犯一些只有流利的使用者才能发现的细微错误:语体不对、措辞不自然、技术术语不正确。
- 流利的使用者必须在正在运行的管理后台界面中预览翻译。AI 工具无法感知布局限制或界面上下文。
- 在 PR 描述中说明使用了 AI。
- 包含未经监督的机器翻译的 PR 将被关闭。
部分翻译
欢迎提交部分翻译。你不需要在一个 PR 中翻译所有字符串,任何进展都有帮助。未翻译的字符串会在运行时回退到英文。