CLI 支持翻译 18 种文件格式。系统会根据文件扩展名自动判断格式;你也可以在 format 条目中设置 files[] 手动覆盖——以及用于那 3 种始终需要显式指定的格式(yaml-openapi、yaml-root-key、android)。
| 格式 | 扩展名 | format 值 | 说明 |
|---|---|---|---|
| JSON | .json | json | 键值对。支持 键控制。 |
| JSONC | .jsonc | jsonc | 带注释的 JSON。注释会被保留,也可直接作为 译者注释 使用。 |
| YAML | .yaml, .yml | yaml | 通用 YAML。所有字符串值都会被翻译;键名和结构保持不变。 |
| OpenAPI YAML | .yaml, .yml | yaml-openapi | OpenAPI 规范。请显式设置 format——普通的 .yaml 会自动识别为 yaml。 |
| 以 locale 为根键的 YAML | .yaml, .yml | yaml-root-key | locale 是 YAML 的根键(Rails config/locales)。根键会被改写为目标 locale。请显式设置 format。 |
| Markdown | .md | md | 默认翻译正文;frontmatter 需手动启用。 |
| MDX | .mdx | mdx | Markdown + JSX。组件 props 需手动启用。 |
| Markdoc | .mdoc | markdoc | Markdown + 标签。支持 frontmatter 和标签属性。 |
| TypeScript | .ts, .mts, .cts | typescript | 语言环境模块(export default { … })。字符串字面量会被翻译;代码保持不变。 |
| Gettext PO | .po | po | 会翻译 msgstr;msgid、注释和头信息保持不变。 |
| Flutter ARB | .arb | flutter | 字符串值会被翻译;@ 元数据和 {placeholders} 保持不变。 |
| Android | .xml | android | strings.xml。请显式设置 format——.xml 不会被自动识别。 |
| Xcode strings | .strings | xcode-strings | 值会被翻译;键保持不变。 |
| Xcode String Catalog | .xcstrings | xcode-xcstrings | 一个文件包含所有语言环境——目标语言会写回同一个文件中(见下文)。 |
| Xcode stringsdict | .stringsdict | xcode-stringsdict | 复数字符串会被翻译;格式控制键保持不变。 |
| XLIFF | .xlf, .xliff | xliff | 保留 <source>,并按单元写入 <target>。支持 1.2 和 2.0 版本。 |
| SubRip | .srt | srt | 字幕文本会被翻译;序号和时间码保持不变。 |
| PHP | .php | php | Laravel return [ … ]。字符串值会被翻译;键、数字和结构保持不变。 |
看一遍完整流程
demo project 是一个小巧的 Sandbox,涵盖文档和数据格式——JSON、JSONC、Markdown、MDX、Markdoc 和 OpenAPI YAML——并为每种格式提供所需的准确配置。使用 npx degit lingodotdev/lingo.dev/demo/new-cli my-lingo-demo 克隆后,运行一次 push 即可。它不包含应用和框架格式——这部分内容可在 Example projects 中查看,每个框架都对应一个完整仓库;而下方按格式列出的代码片段则涵盖了相应配置。
npx degit lingodotdev/lingo.dev/demo/new-cli my-lingo-demo
cd my-lingo-demoJSON 和 JSONC#
标准的键值对翻译。除非通过 键控制 另行指定,否则所有字符串值都会被翻译。
{ "pattern": "content/en/app.json", "lockedKeys": ["meta.version"] }JSONC 还会保留注释,引擎也会将这些注释作为上下文读取——参见 译者注释。
{ "pattern": "content/en/settings.jsonc", "preservedKeys": ["featureFlags"] }Markdown、MDX 和 Markdoc#
默认会翻译正文内容。frontmatter 和内嵌组件不会被翻译,除非你手动启用。
Frontmatter#
使用 translateFrontmatterFields 列出需要翻译的 frontmatter 字段:
{
"pattern": "content/en/guide.md",
"translateFrontmatterFields": ["title", "description"]
}MDX 组件 props#
对于 MDX,可通过 translateComponentProps 为特定组件上的特定 props 开启翻译:
{
"pattern": "content/en/landing.mdx",
"translateFrontmatterFields": ["title"],
"translateComponentProps": [{ "component": ["Hero", "Callout"], "props": ["title", "body"] }]
}这样会翻译 title 和 body 上的 <Hero> 与 <Callout> props,其余所有 props 都保持不变。
Markdoc#
Markdoc 的处理方式与 Markdown 类似,同时保留 frontmatter 和标签属性:
{
"pattern": "content/en/changelog.mdoc",
"translateFrontmatterFields": ["title"]
}YAML#
通用 YAML 会根据 .yaml/.yml 自动识别——所有字符串值都会被翻译,键名和结构保持不变:
{ "pattern": "content/en/strings.yaml" }OpenAPI 规范属于特殊情况:虽然同样使用 .yaml 扩展名,但必须显式指定 format,这样引擎才只会翻译面向用户的字段(如摘要、描述),同时保留 schema 键、路径和操作 ID:
{ "pattern": "content/en/api.yaml", "format": "yaml-openapi" }另一种特殊情况是 Rails 风格的 locale 文件:locale 是 YAML 的根键(en:),而目标文件也必须以目标 locale(es:)作为根键。这类文件同样需要显式设置 format:
{ "pattern": "config/locales/en.yml", "format": "yaml-root-key" }应用与框架格式#
PO、Flutter ARB、Xcode .strings、Xcode .stringsdict、TypeScript 语言环境模块、XLIFF、SubRip 和 PHP 都遵循同一条规则:该翻译的文本会被翻译,所有结构性内容都会被保留(键、ID、元数据、占位符、时间码、代码、格式)。这些格式都会根据扩展名自动识别——只需将模式指向源文件即可:
{ "pattern": "lib/l10n/app_en.arb" }
{ "pattern": "locales/en.po" }
{ "pattern": "Localizable.strings" }
{ "pattern": "l10n/en.xlf" }其中有一种必须显式指定 format,因为它的扩展名歧义太大,无法自动识别:
{ "pattern": "res/values/strings.xml", "format": "android" }Xcode String Catalogs#
.xcstrings(String Catalog)文件会将所有语言环境集中在同一个文件里。它没有按语言环境区分的输出路径——CLI 会读取源语言环境,并将所有目标语言写回这个文件:
{ "pattern": "Localizable.xcstrings" }catalog 中标记为 "shouldTranslate": false 的字符串将被跳过——CLI 不会翻译,也不会对其做任何改动。
输出路径#
这个模式用于指定你的源文件;所有目标路径都会由此推导出来。按顺序适用以下四条规则:
- 整个路径段或文件名就是 locale——这是最常见的情况。
content/en/app.json→content/de/app.json,locales/en.json→locales/de.json。 - locale 出现在路径段或文件名的末尾,适用于采用这种命名方式的布局——Android、Xcode 的
.strings/.stringsdict、Flutter,以及yaml-root-key。res/values-en/→res/values-de/,app_en.arb→app_de.arb,devise.en.yml→devise.de.yml。 - 平台为默认语言预留的名称,路径中完全不带 locale。 Android 中不带后缀的
res/values/会变成res/values-de/,Xcode 中的Base.lproj会变成de.lproj。 - String Catalog:目标路径就是源路径,因为同一个文件承载了所有 locale。
Android 是唯一一个目标路径不采用 BCP 47 的平台:CLI 会写入 Android 实际识别的资源限定符,因此 pt-BR 会落到 values-pt-rBR/,zh-Hans 会落到 values-b+zh+Hans/。
如果没有任何规则匹配——也就是源 locale 在路径中完全没有出现——CLI 会回退为在文件旁创建一个 <locale>/ 目录,而 lingo push 会明确提示这是根据推测生成的。请把这个警告视为模式写错了的信号。参见 Configuration。
从旧版 CLI 迁移?#
旧版 CLI 支持的大多数格式,当前 CLI 都已覆盖(PO、XLIFF、Android/Xcode strings、Flutter ARB 等——见上表)。少数较少见的格式(如 CSV、HTML、MJML、.properties)暂未支持;在你的格式上线前,可先参考 legacy CLI docs。
