在你將元件準備好進行翻譯之後,可以使用 extract-i18n Angular CLI 指令,將元件中標記的文字擷取到一個來源語言(source language)檔案中。
標記的文字包括以 i18n 標記的文字、以 i18n-attribute 標記的屬性,以及如為翻譯準備元件所述以 $localize 標記的文字。
請完成下列步驟,為你的專案建立並更新翻譯檔案。
擷取來源語言檔案
若要擷取來源語言檔案,請完成下列動作。
- 開啟終端機視窗。
- 切換到你專案的根目錄。
- 執行下列 CLI 指令。
ng extract-i18n
extract-i18n 指令會在你專案的根目錄中,建立一個名為 messages.xlf 的來源語言檔案。
有關 XML Localization Interchange File Format(XLIFF,version 1.2)的更多資訊,請參閱 XLIFF。
使用下列 extract-i18n 指令選項,可以變更來源語言檔案的位置、格式與檔案名稱。
| 指令選項 | 說明 |
|---|---|
--format |
設定輸出檔案的格式 |
--out-file |
設定輸出檔案的名稱 |
--output-path |
設定輸出目錄的路徑 |
變更來源語言檔案的位置
若要在 src/locale 目錄中建立檔案,請將輸出路徑指定為選項。
extract-i18n --output-path 範例
下列範例將輸出路徑指定為選項。
ng extract-i18n --output-path src/locale
變更來源語言檔案的格式
extract-i18n 指令可以建立下列翻譯格式的檔案。
| 翻譯格式 | 說明 | 副檔名 |
|---|---|---|
| ARB | Application Resource Bundle | .arb |
| JSON | JavaScript Object Notation | .json |
| XLIFF 1.2 | XML Localization Interchange File Format, version 1.2 | .xlf |
| XLIFF 2 | XML Localization Interchange File Format, version 2 | .xlf |
| XMB | XML Message Bundle | .xmb (.xtb) |
使用 --format 指令選項明確指定翻譯格式。
HELPFUL: XMB 格式會產生 .xmb 來源語言檔案,但翻譯檔案使用的是 .xtb。
extract-i18n --format 範例
下列範例示範了幾種翻譯格式。
ng extract-i18n --format=xlf
ng extract-i18n --format=xlf2
ng extract-i18n --format=xmb
ng extract-i18n --format=json
ng extract-i18n --format=arb
變更來源語言檔案的名稱
若要變更擷取工具產生的來源語言檔案名稱,請使用 --out-file 指令選項。
extract-i18n --out-file 範例
下列範例示範如何為輸出檔案命名。
ng extract-i18n --out-file source.xlf
為每種語言建立一個翻譯檔案
若要為某個地區設定(locale)或語言建立翻譯檔案,請完成下列動作。
複製一份來源語言檔案,為每種語言建立一個翻譯檔案。
重新命名翻譯檔案,加上地區設定。
messages.xlf --> messages.{locale}.xlf在你專案的根目錄建立一個名為
locale的新目錄。src/locale將翻譯檔案移到新目錄中。
將翻譯檔案送交你的譯者。
對你想加入應用程式的每種語言,重複上述步驟。
法文的 extract-i18n 範例
例如,若要建立法文翻譯檔案,請完成下列動作。
- 執行
extract-i18n指令。 - 複製一份
messages.xlf來源語言檔案。 - 將複本重新命名為
messages.fr.xlf,作為法文(fr)翻譯。 - 將
fr翻譯檔案移到src/locale目錄。 - 將
fr翻譯檔案送交譯者。
翻譯每個翻譯檔案
除非你精通該語言,而且有時間編輯翻譯,否則你很可能會完成下列步驟。
- 將每個翻譯檔案送交譯者。
- 譯者使用 XLIFF 檔案編輯器完成下列動作。
- 建立翻譯。
- 編輯翻譯。
法文翻譯流程範例
為了示範流程,請檢視範例 Angular 國際化應用程式中的 messages.fr.xlf 檔案。範例 Angular 國際化應用程式包含一份法文翻譯,讓你無需特殊的 XLIFF 編輯器或法文知識就能編輯。
下列動作說明法文的翻譯流程。
開啟
messages.fr.xlf,找出第一個<trans-unit>元素。 這是一個翻譯單元(translation unit),也稱為文字節點(text node),代表先前以i18n屬性標記的<h1>問候標籤的翻譯。src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="introductionHeader" datatype="html"> <source>Hello i18n!</source> <note priority="1" from="description">An introduction header for this sample</note> <note priority="1" from="meaning">User welcome</note> </trans-unit>id="introductionHeader"是一個自訂 ID,但不含來源 HTML 中要求的@@前綴。複製文字節點中的
<source>... </source>元素,將它重新命名為target,然後把內容換成法文文字。src/locale/messages.fr.xlf (<trans-unit>,翻譯後)
<trans-unit id="introductionHeader" datatype="html"> <source>Hello i18n!</source> <target>Bonjour i18n !</target> <note priority="1" from="description">An introduction header for this sample</note> <note priority="1" from="meaning">User welcome</note> </trans-unit>在較複雜的翻譯中,說明與含義元素中的資訊與上下文,能協助你選擇正確的翻譯用詞。
翻譯其他文字節點。 下列範例顯示翻譯的方式。
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="ba0cc104d3d69bf669f97b8d96a4c5d8d9559aa3" datatype="html"> <source>I don't output any element</source> <target>Je n'affiche aucun élément</target> </trans-unit> <trans-unit id="701174153757adf13e7c24a248c8a873ac9f5193" datatype="html"> <source>Angular logo</source> <target>Logo d'Angular</target> </trans-unit>
IMPORTANT: 不要變更翻譯單元的 ID。
每個 id 屬性都是由 Angular 產生的,取決於元件文字的內容與指定的含義。
如果你變更了文字或含義,id 屬性就會改變。
有關管理文字更新與 ID 的更多資訊,請參閱自訂 ID。
翻譯複數形式
依每種語言的需要,新增或移除複數形式(plural cases)。
HELPFUL: 有關語言的複數規則,請參閱 CLDR plural rules。
minute plural 範例
若要翻譯 plural,請翻譯 ICU 格式的比對值。
just nowone minute ago<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago
下列範例顯示翻譯的方式。
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="5a134dee893586d02bffc9611056b9cadf9abfad" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }</source>
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes} }</target>
</trans-unit>
翻譯替代運算式
Angular 也會將替代的 select ICU 運算式擷取為個別的翻譯單元。
gender select 範例
下列範例顯示元件範本中的一個 select ICU 運算式。
app.component.html
<span i18n>The author is {gender, select, male {male} female {female} other {other}}</span>
在此範例中,Angular 將運算式擷取為兩個翻譯單元。
第一個包含 select 子句之外的文字,並為 select 使用一個佔位符(<x id="ICU">):
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="f99f34ac9bd4606345071bd813858dec29f3b7d1" datatype="html">
<source>The author is <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></source>
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></target>
</trans-unit>
IMPORTANT: 翻譯文字時,必要時可以移動佔位符,但不要將它移除。 如果你移除了佔位符,ICU 運算式就會從你翻譯後的應用程式中被移除。
下列範例顯示第二個翻譯單元,其中包含 select 子句。
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="eff74b75ab7364b6fa888f1cbfae901aaaf02295" datatype="html">
<source>{VAR_SELECT, select, male {male} female {female} other {other} }</source>
<target>{VAR_SELECT, select, male {un homme} female {une femme} other {autre} }</target>
</trans-unit>
下列範例顯示翻譯完成後的兩個翻譯單元。
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="f99f34ac9bd4606345071bd813858dec29f3b7d1" datatype="html">
<source>The author is <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></source>
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></target>
</trans-unit>
<trans-unit id="eff74b75ab7364b6fa888f1cbfae901aaaf02295" datatype="html">
<source>{VAR_SELECT, select, male {male} female {female} other {other} }</source>
<target>{VAR_SELECT, select, male {un homme} female {une femme} other {autre} }</target>
</trans-unit>
翻譯巢狀運算式
Angular 處理巢狀運算式的方式,與處理替代運算式相同。 Angular 會將運算式擷取為兩個翻譯單元。
巢狀 plural 範例
下列範例顯示第一個翻譯單元,其中包含巢狀運算式之外的文字。
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="972cb0cf3e442f7b1c00d7dab168ac08d6bdf20c" datatype="html">
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
<target>Mis à jour: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></target>
</trans-unit>
下列範例顯示第二個翻譯單元,其中包含完整的巢狀運算式。
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="7151c2e67748b726f0864fc443861d45df21d706" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, male {male} female {female} other {other} }} }</source>
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes par {VAR_SELECT, select, male {un homme} female {une femme} other {autre} }} }</target>
</trans-unit>
下列範例顯示翻譯後的兩個翻譯單元。
src/locale/messages.fr.xlf (<trans-unit>)
<trans-unit id="972cb0cf3e442f7b1c00d7dab168ac08d6bdf20c" datatype="html">
<source>Updated: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></source>
<target>Mis à jour: <x id="ICU" equiv-text="{minutes, plural, =0 {...} =1 {...} other {...}}"/></target>
</trans-unit>
<trans-unit id="7151c2e67748b726f0864fc443861d45df21d706" datatype="html">
<source>{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago by {VAR_SELECT, select, male {male} female {female} other {other} }} }</source>
<target>{VAR_PLURAL, plural, =0 {à l'instant} =1 {il y a une minute} other {il y a <x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes par {VAR_SELECT, select, male {un homme} female {une femme} other {autre} }} }</target>
</trans-unit>