跳到主要内容

国际化 - 使用 Crowdin

Docusaurus 的国际化系统 与任何翻译软件无关 。

您可以将 Docusaurus 与 您选择的工具和 SaaS 集成 ,只要您将 翻译文件放在正确的位置 即可。

我们记录了 Crowdin 的用法,作为一个可能的 集成示例 。

注意

这不是对 Crowdin 作为翻译 Docusaurus 网站的唯一选择的 认可 ,但 Facebook 成功地使用它来翻译文档项目,例如 Jest 、 Docusaurus 和 ReasonML 。

请参考 Crowdin 文档 和 Crowdin 支持 获取帮助。

提示

使用此 社区驱动的 GitHub 讨论 来讨论与 Docusaurus + Crowdin 相关的任何内容。

Crowdin 概述​

Crowdin 是一款翻译 SaaS,为 开源项目提供免费计划 。

我们推荐以下翻译工作流程:

  • 将 源文件 上传到 Crowdin(未翻译的文件)
  • 使用 Crowdin 翻译内容
  • 从 Crowdin 下载翻译 (本地化翻译文件)

Crowdin 提供了一个 CLI 来 上传源文件 和 下载翻译 ,允许您自动化翻译过程。

crowdin.yml 配置文件 对于 Docusaurus 来说很方便,并且允许 将本地化翻译文件下载到预期位置 (在 i18n/[locale]/.. 中)。

阅读 官方文档 以了解有关高级功能和不同翻译工作流程的更多信息。

Crowdin 教程​

这是一个使用 Crowdin 将新初始化的英文 Docusaurus 网站翻译成法文的演练,并假设您已遵循 国际化教程 。

最终结果可以在 docusaurus-crowdin-example.netlify.app (代码库) 中看到。

准备 Docusaurus 站点​

初始化一个新的 Docusaurus 站点:

npx create-docusaurus@latest website classic

添加法语的站点配置:

docusaurus.config.js
export default {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
themeConfig: {
navbar: {
items: [
// ...
{
type: 'localeDropdown',
position: 'left',
},
// ...
],
},
},
// ...
};

翻译主页:

src/pages/index.js
import React from 'react';
import Translate from '@docusaurus/Translate';
import Layout from '@theme/Layout';

export default function Home() {
return (
<Layout>
<h1 style={{margin: 20}}>
<Translate description="The homepage main heading">
Welcome to my Docusaurus translated site!
</Translate>
</h1>
</Layout>
);
}

创建 Crowdin 项目​

在 Crowdin 上注册,并创建一个项目。

使用英语作为源语言,法语作为目标语言。

使用英语作为源语言,法语作为目标语言创建 Crowdin 项目

您的项目已创建,但目前为空。我们将在接下来的步骤中上传要翻译的文件。

创建 Crowdin 配置​

此配置 (文档) 为 Crowdin CLI 提供了一个映射,以便理解:

  • 在哪里查找要上传的源文件(JSON 和 Markdown)
  • 翻译后在哪里下载文件(在 i18n/[locale] 中)

在 website 中创建 crowdin.yml:

crowdin.yml
project_id: '123456'
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true
files:
# JSON 翻译文件
- source: /i18n/en/**/*
translation: /i18n/%two_letters_code%/**/%original_file_name%
# Docs Markdown 文件
- source: /docs/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
# Blog Markdown 文件
- source: /blog/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name%

Crowdin 有自己声明源/翻译路径的语法:

  • **/*:子文件夹中的所有内容
  • %two_letters_code%:Crowdin 目标语言的 2 个字母的变体(在本例中为 fr)
  • **/%original_file_name%:翻译将保留原始文件夹/文件的层次结构
信息

Crowdin CLI 警告并不总是很容易理解。

我们建议:

  • 一次更改一件事情
  • 在任何配置更改后重新上传源文件
  • 使用以 / 开头的路径(./ 不起作用)
  • 避免使用花哨的通配符模式,例如 /docs/**/*.(md|mdx)(不起作用)

访问令牌​

api_token_env 属性定义了 Crowdin CLI 读取的 环境变量名称 。

您可以在 您的个人资料页面 上获取 个人访问令牌。

提示

您可以保留默认值 CROWDIN_PERSONAL_TOKEN,并在您的计算机和 CI 服务器上将此环境变量设置为生成的访问令牌。

注意

个人访问令牌授予 对所有 Crowdin 项目的读写访问权限 。

您 不应提交 它,并且创建一个专门的 公司 Crowdin 个人资料 而不是使用个人帐户可能是一个好主意。

其他配置字段​

  • project_id:可以硬编码,可以在 https://crowdin.com/project/<MY_PROJECT_NAME>/settings#api 上找到
  • preserve_hierarchy:在 Crowdin UI 上保留文档的文件夹层次结构,而不是将所有内容都扁平化

安装 Crowdin CLI​

本教程使用 CLI 版本 3.5.2,但我们预计 3.x 版本将继续工作。

将 Crowdin CLI 作为 npm 包安装到您的 Docusaurus 站点:

npm install @crowdin/cli@3

添加 crowdin 脚本:

package.json
{
"scripts": {
// ...
"write-translations": "docusaurus write-translations",
"crowdin": "crowdin"
}
}

测试您可以运行 Crowdin CLI:

npm run crowdin -- --version

在您的计算机上设置 CROWDIN_PERSONAL_TOKEN 环境变量,以允许 CLI 使用 Crowdin API 进行身份验证。

提示

暂时,您可以使用 api_token: 'MY-TOKEN' 在 crowdin.yml 中硬编码您的个人令牌。

上传源文件​

为 website/i18n/en 中的默认语言生成 JSON 翻译文件:

npm run write-translations

上传所有 JSON 和 Markdown 翻译文件:

npm run crowdin upload

Crowdin CLI 上传 Docusaurus 源文件

您的源文件现在可在 Crowdin 界面上看到:https://crowdin.com/project/<MY_PROJECT_NAME>/settings#files

Crowdin UI 显示 Docusaurus 源文件

翻译源文件​

在 https://crowdin.com/project/<MY_PROJECT_NAME> 上,单击法语目标语言。

Crowdin UI 显示法语翻译文件

翻译一些 Markdown 文件。

Crowdin UI 翻译 Markdown 文件

提示

使用“隐藏字符串”确保译者 不会翻译不应翻译的内容 :

  • 前置 matter:id、slug、tags ...
  • 警告::::、:::note、:::tip ...

Crowdin UI 隐藏字符串

翻译一些 JSON 文件。

Crowdin UI 翻译 JSON 文件

信息

JSON 翻译文件的 description 属性在 Crowdin 上可见,有助于翻译字符串。

提示

预翻译您的网站,并 手动更正预翻译错误(首先启用设置中的全局翻译内存)。

首先使用“隐藏字符串”功能,因为 Crowdin 过于乐观地进行预翻译。

下载翻译​

使用 Crowdin CLI 下载已翻译的 JSON 和 Markdown 文件。

npm run crowdin download

已翻译的内容应下载到 i18n/fr 中。

在法语区域设置下启动您的站点:

npm run start -- --locale fr

确保您的网站现在已翻译成法语,网址为 http://localhost:3000/fr/ 。

使用 CI 自动化​

我们将配置 CI 以 在构建时下载 Crowdin 翻译 并将它们保存在 Git 之外。

将 website/i18n 添加到 .gitignore。

在您的 CI 上设置 CROWDIN_PERSONAL_TOKEN 环境变量。

创建一个 npm 脚本以 sync Crowdin(提取源文件、上传源文件、下载翻译):

package.json
{
"scripts": {
"crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download"
}
}

在您的 CI 中调用 npm run crowdin:sync 脚本,就在构建 Docusaurus 站点之前。

提示

保持您的部署预览快速:不要下载翻译,并对功能分支使用 npm run build -- --locale en。

注意

Crowdin 不太支持多个并发上传/下载:最好只将翻译包含到您的生产部署中,并将部署预览保持为未翻译状态。

高级 Crowdin 主题​

MDX​

注意

特别注意 MDX 文档中的 JSX 片段!

Crowdin 官方不支持 MDX ,但他们添加了对 .mdx 扩展名的 支持 ,并将此类文件解释为 Markdown(而不是纯文本)。

MDX 问题​

Crowdin 认为 JSX 语法是嵌入式 HTML,并且在您下载翻译时可能会弄乱 JSX 标记,从而导致站点由于无效的 JSX 而无法构建。

使用简单字符串属性的简单 JSX 片段(例如 <Username name="Sebastien"/>)可以正常工作;更复杂的 JSX 片段使用对象/数组属性(例如 <User person={{name: "Sebastien"}}/>)更有可能由于看起来不像 HTML 的语法而失败。

MDX 解决方案​

我们建议将复杂的嵌入式 JSX 代码提取为单独的独立组件。我们还添加了一个 mdx-code-block 规避语法:

# 如何部署 Docusaurus

要部署 Docusaurus,请运行以下命令:

````mdx-code-block 

import Tabs from '@theme/Tabs';

import TabItem from '@theme/TabItem';

<Tabs>
<TabItem value="bash" label="Bash">

```bash
GIT_USER=<GITHUB_USERNAME> yarn deploy
```

</TabItem>
<TabItem value="windows" label="Windows">

```batch
cmd /C "set "GIT_USER=<GITHUB_USERNAME>" && yarn deploy"
```

</TabItem>
</Tabs>
````

这将:

  • 被 Crowdin 解释为代码块(并且不会在下载时弄乱标记)
  • 被 Docusaurus 解释为常规 JSX(就像它没有被任何代码块包装一样)
  • 不幸的是,选择不使用 MDX 工具(IDE 语法高亮显示、Prettier……)

文档版本控制​

配置 website/versioned_docs 文件夹的翻译文件。 创建新版本时,源字符串通常与当前版本(website/docs)非常相似,您不希望一次又一次地翻译新版本文档。

Crowdin 提供了一个“重复字符串”设置。

Crowdin 重复字符串选项设置

我们建议使用“隐藏”,但理想设置取决于您的版本差异程度。

注意

不使用“隐藏”会导致配额中的“源字符串”数量大幅增加,并会影响价格。

多实例插件​

您需要为每个插件实例配置翻译文件。

如果您有一个 id=ios 的文档插件实例,您也需要配置这些源文件

  • website/ios
  • website/ios_versioned_docs(如果已版本化)

维护您的站点​

有时,您会在 Git 上 删除或重命名源文件 ,Crowdin 将显示 CLI 警告:

Crowdin CLI:下载翻译警告

当您的源文件被重构时,您应该使用 Crowdin UI 手动更新您的 Crowdin 文件 :

Crowdin UI:重命名文件

VCS(Git)集成​

Crowdin 为 GitHub 、GitLab、Bitbucket 提供多种 VCS 集成。

TL;DR

我们建议避免使用它们。

能够同时在 Git 和 Crowdin 中编辑翻译,并在两个系统之间进行 双向同步 本来是有帮助的。

实际上,由于以下几个原因, 它并没有非常可靠地工作 :

  • Crowdin -> Git 同步工作正常(带有拉取请求)
  • Git -> Crowdin 同步是手动的(您必须按下按钮)
  • Crowdin 用于将现有 Markdown 翻译与现有 Markdown 源匹配的启发式方法并非 100% 可靠,您必须在从 Git 同步后在 Crowdin UI 上验证结果
  • 两个用户同时在 Git 和 Crowdin 上编辑可能会导致翻译丢失
  • 它需要 crowdin.yml 文件位于存储库的根目录

上下文内本地化​

Crowdin 具有 上下文内本地化 功能。

注意

不幸的是,由于技术原因,它尚无法工作,但我们有理由相信它可以解决。

Crowdin 将 Markdown 字符串替换为技术 ID,例如 crowdin:id12345,但它过于积极地这样做,包括隐藏的字符串,并弄乱了前置 matter、警告、JSX……

本地化编辑 URL​

当用户浏览 /fr/doc1 中的页面时,编辑按钮默认会链接到 website/docs/doc1.md 中未本地化的文档。

您可以更倾向于让编辑按钮链接到 Crowdin 界面,方法是使用 editUrl 函数根据每个区域设置自定义编辑 URL。

docusaurus.config.js
const DefaultLocale = 'en';

export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
editUrl: ({locale, versionDocsDirPath, docPath}) => {
// 链接到法语文档的 Crowdin
if (locale !== DefaultLocale) {
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
}
// 链接到英文文档的 GitHub
return `https://github.com/facebook/docusaurus/edit/main/website/${versionDocsDirPath}/${docPath}`;
},
},
blog: {
editUrl: ({locale, blogDirPath, blogPath}) => {
if (locale !== DefaultLocale) {
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
}
return `https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`;
},
},
},
],
],
};
备注

目前 无法链接到 Crowdin 中的特定文件 。

示例配置​

Docusaurus 配置文件是使用版本控制和多实例的一个很好的例子:

crowdin.yml
project_id: '428890'
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true
languages_mapping: &languages_mapping
two_letters_code:
pt-BR: pt-BR
files:
- source: /website/i18n/en/**/*
translation: /website/i18n/%two_letters_code%/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/docs/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/community/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs-community/current/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/versioned_docs/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/blog/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/src/pages/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-pages/**/%original_file_name%
ignore: [/**/*.js, /**/*.jsx, /**/*.ts, /**/*.tsx, /**/*.css]
languages_mapping: *languages_mapping

机器翻译 (MT) 问题:链接/图像处理​

Crowdin 最近对 markdown 文件格式进行了一些重大更改,现在链接的处理方式与以前不同。以前它们被视为标签,但现在它们显示为纯文本。由于这些更改,纯文本链接被传递到 MT 引擎,该引擎尝试翻译目标,从而破坏翻译(例如:字符串 Allez voir [ma merveilleuse page](/ma-merveilleuse-page) 被翻译为 Check out [my wonderful page](/my-wonderful-page) ,这会破坏 docusaurus i18n 工作流程,因为页面名称不应翻译)。

截至 2023 年 12 月 7 日,他们不打算更改链接处理方式的逻辑,因此如果您计划将 Crowdin 与 MT 一起使用,则应牢记这一点。