i18n - 使用 Crowdin
Docusaurus 的 i18n 系統 與任何翻譯軟體脫鉤。
只要你將 翻譯檔案放置在正確位置,你就可以將 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/[地區代碼]/..
中)下載在地化翻譯檔案。
閱讀官方文件以瞭解進階功能和不同的翻譯工作流程。
Crowdin 教學
以下為使用 Crowdin 將新初始化的英文 Docusaurus 網站翻譯成法文的範例,並假設您已追蹤i18n 教學。
最終成果可以在 docusaurus-crowdin-example.netlify.app(儲存庫)中看見。
準備 Docusaurus 網站
初始化一個新 Docusaurus 網站
npx create-docusaurus@latest website classic
加入法語網站組態
export default {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
themeConfig: {
navbar: {
items: [
// ...
{
type: 'localeDropdown',
position: 'left',
},
// ...
],
},
},
// ...
};
翻譯首頁
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 CLI 能了解
- 在哪裡找到要上傳的原始檔案 (JSON 和 Markdown)
- 在翻譯後下載檔案的位置 (在
i18n/[地區]
)
在 website
中建立 crowdin.yml
project_id: '123456'
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true
files:
# JSON translation files
- source: /i18n/en/**/*
translation: /i18n/%two_letters_code%/**/%original_file_name%
# Docs Markdown files
- source: /docs/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
# Blog Markdown files
- source: /blog/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name%
Crowdin 有自己的語法來宣告原始檔/翻譯路徑
**/*
:子資料夾中的一切%two_letters_code%
:Crowdin 目標語言的兩字母變體 (本例中為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 安裝為 Docusaurus 站台的 npm 套件
- npm
- Yarn
- pnpm
npm install @crowdin/cli@3
yarn add @crowdin/cli@3
pnpm add @crowdin/cli@3
新增 crowdin
腳本
{
"scripts": {
// ...
"write-translations": "docusaurus write-translations",
"crowdin": "crowdin"
}
}
測試是否可以執行 Crowdin CLI
- npm
- Yarn
- pnpm
npm run crowdin -- --version
yarn crowdin --version
pnpm run crowdin --version
在電腦上設定 CROWDIN_PERSONAL_TOKEN
環境變數,讓 CLI 可以通過 Crowdin API 驗證。
暫時可以在 crowdin.yml
中以 api_token: '我的代碼'
硬式編寫你的個人代碼。
上傳原始檔
在 website/i18n/en
中為預設語言產生 JSON 翻譯檔
- npm
- Yarn
- pnpm
npm run write-translations
yarn write-translations
pnpm run write-translations
上傳所有 JSON 和 Markdown 翻譯檔
- npm
- Yarn
- pnpm
npm run crowdin upload
yarn crowdin upload
pnpm run crowdin upload
你的原始檔現在可在 Crowdin 介面中看到:https://crowdin.com/project/<我的專案名稱>/settings#files
翻譯原始檔
在 https://crowdin.com/project/<我的專案名稱>
中,點選法文目標語言。
翻譯一些 Markdown 檔案。
使用「隱藏字串」來確定翻譯者不翻譯不應被翻譯的內容
- 前端事項:
id
、slug
、tags
... - 警告:
:::
、:::note
、:::tip
...
翻譯一些 JSON 檔案。
JSON 翻譯檔的 description
屬性在 Crowdin 中可用來協助翻譯字串。
預翻譯你的站台,並手動修正預翻譯錯誤(先在設定中啟用「全球翻譯記憶體」)。
先使用「隱藏字串」功能,因為 Crowdin 在預翻譯時過於樂觀。
下載翻譯
使用 Crowdin CLI 下載已翻譯的 JSON 及 Markdown 檔案。
- npm
- Yarn
- pnpm
npm run crowdin download
yarn crowdin download
pnpm run crowdin download
已翻譯的內容會下載到 i18n/fr
。
在法文區域設定中開啟你的站台
- npm
- Yarn
- pnpm
npm run start -- --locale fr
yarn run start --locale fr
pnpm run start --locale fr
確認你的網站現在已翻譯成法文,網址為 https://127.0.0.1:3000/fr/
。
利用 CI 自動化
我們會組態 CI,讓它在建置時下載 Crowdin 翻譯並將它們保留在 Git 外部。
將 website/i18n
新增到 .gitignore
。
在 CI 中設定 CROWDIN_PERSONAL_TOKEN
環境變數。
建立 npm 腳本来 同步
Crowdin(萃取原始檔、上傳原始檔、下載翻譯)
{
"scripts": {
"crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download"
}
}
在建置 Docusaurus 網站之前,請在 CI 中呼叫 npm run crowdin:sync
指令碼。
確保部署預覽快速無礙:請勿下載翻譯,並針對功能分支使用 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
跳脫逃生艙語法
# How to deploy Docusaurus
To deploy Docusaurus, run the following command:
````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 提供 重複字串
設定。
我們建議使用 隱藏
,但理想的設定取決於不同版本之間的差異程度。
不使用 隱藏
會導致在配額中累積大量的 原始字串
,並影響價格。
多執行個體外掛程式
您需要為每個外掛程式執行個體設定翻譯檔案。
如果您有一個 id=ios 的文件外掛程式執行個體,您也需要設定這些原始檔案
website/ios
website/ios_versioned_docs
(如果經過版本化)
維護您的網站
有時候,您會在 Git 上移除或重新命名來源檔案,Crowdin 會顯示 CLI 警告
當您的來源重構時,您應使用 Crowdin UI 來手動更新您的 Crowdin 檔案
VCS(Git)整合
Crowdin 具有多種 VCS 整合,可用於 GitHub、GitLab、Bitbucket。
我們建議避開這些檔案。
能夠在 Git 和 Crowdin 中編輯翻譯並在兩個系統之間具有雙向同步會有所幫助。
實際上,由於以下原因,其並未非常可靠地運作
- Crowdin -> Git 同步運作良好(透過拉取要求)
- Git -> Crowdin 同步為手動(您必須按下按鈕)
- Crowdin 用於將現有的 Markdown 翻譯與現有的 Markdown 來源配對所使用的啟發法並非 100% 可靠,且您必須在從 Git 進行任何同步後在 Crowdin UI 上驗證結果
- 2 個使用者同時在 Git 和 Crowdin 上編輯可能會導致翻譯遺失
- 它需要
crowdin.yml
檔案位於儲存庫的根目錄
脈絡翻譯
Crowdin 有一個脈絡翻譯功能。
很不幸地,由於技術原因,它尚未能運作,但我們深信它可以解決。
Crowdin 使用技術 ID(例如 crowdin:id12345
)取代 Markdown 字串,但過於積極,包括隱藏字串、搞亂前端、警告、JSX...
在地化編輯網址
當使用者瀏覽 /fr/doc1
頁面時,編輯按鈕會預設連結到 website/docs/doc1.md
上未在地化的文件。
您可能傾向使用 editUrl
函數在每個區域的基礎上自訂編輯網址,將編輯按鈕連結到 Crowdin 介面。
const DefaultLocale = 'en';
export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
editUrl: ({locale, versionDocsDirPath, docPath}) => {
// Link to Crowdin for French docs
if (locale !== DefaultLocale) {
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
}
// Link to GitHub for English docs
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 設定檔是使用版本管理和多個執行個體的範例
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 搭配使用,您應該考慮這一點。