翻译 EmDash

本页内容

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 会在运行时回退到英文。

翻译字符串

  1. 查看翻译仪表板,了解哪些内容需要处理。检查未关闭的 PR,避免重复劳动。

  2. Fork 仓库并创建分支:

    git checkout -b i18n/de
  3. 打开你所用语言的 PO 文件(例如 packages/admin/src/locales/de/messages.po)。

  4. 填写翻译。 每个条目如下所示:

    #: 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"
  5. 测试你的翻译(见下文)。

  6. 向 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 组件。两者都必须在你的翻译中与源文本完全一致地出现,名称和嵌套结构都不能改变。

测试你的翻译

  1. 编译并运行演示:

    pnpm run locale:compile
    pnpm build
    pnpm --filter emdash-demo dev
  2. 在管理后台的设置页面中切换语言,并确认你的翻译在上下文中看起来正确。

伪语言环境

EmDash 内置了一个伪语言环境(pseudo locale),它会把所有被包裹的字符串变成带重音符号的相似字符,例如 "Dashboard" 会变成 "Ðàšĥƀöàřð"。在伪语言环境启用时,任何仍以普通英文显示的字符串,要么缺少 t\…“ 包裹,要么来自目录之外。

要启用它,请在演示目录的 .env 文件中添加以下内容:

EMDASH_PSEUDO_LOCALE=1

然后重启开发服务器。伪语言环境会以 Pseudo 的名称出现在登录页面和设置中的语言选择器里。切换到它,就能一眼发现未被包裹的字符串。

添加新语言

如果你的语言还没有 PO 文件:

  1. 将该语言添加到 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。当该语言的覆盖率足以在管理后台界面中使用时,由维护者将其启用。

  2. 运行提取,生成空的 PO 文件:

    pnpm run locale:extract

    这会创建 packages/admin/src/locales/{your-locale}/messages.po,其中包含所有待翻译的字符串。

  3. 按照上述步骤翻译并测试。

翻译标准

准确性

翻译应以母语者的水准忠实地呈现英文源文本。不要增加、删减或重新解读含义。如果源字符串有歧义,请查看 #: 注释中的源文件位置,并阅读组件代码以理解上下文。

一致性

在你的语言中使用一致的术语。如果你在某处把 “collection” 译为 “Sammlung”,就不要在别处改用 “Kollektion”。如果你的语言已有翻译,请在开始之前通读现有的 PO 文件,以匹配既定术语。

语气

管理后台界面采用直接、专业的语气。请在你的语言中保持一致,避免过于正式或过于随意的措辞。

AI 辅助翻译

你可以使用 AI 工具生成翻译,包括完整的初稿,但必须由流利的使用者监督结果:

  • 流利的使用者必须审阅每一个字符串。AI 工具会犯一些只有流利的使用者才能发现的细微错误:语体不对、措辞不自然、技术术语不正确。
  • 流利的使用者必须在正在运行的管理后台界面中预览翻译。AI 工具无法感知布局限制或界面上下文。
  • 在 PR 描述中说明使用了 AI。
  • 包含未经监督的机器翻译的 PR 将被关闭。

部分翻译

欢迎提交部分翻译。你不需要在一个 PR 中翻译所有字符串,任何进展都有帮助。未翻译的字符串会在运行时回退到英文。