可以透過CLI來產生XLS檔案,並透過XLS檔案來設定多語系字串,接著使用下面的字串來產生網站檔案:
ng serve --aot --locale zh-Hant
假如是使用JIT的方式去佈暑網站,則也要在頁面設定LOCALE_ID的值如下:
import { LOCALE_ID, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from '../src/app/app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [ { provide: LOCALE_ID, useValue: 'zh-Hant' } ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
從上面的範例可以看出,Angular多語系的實作方式是讓每個語言獨立一個index.html
版本。這樣優點是網站瀏覽較為快速,缺點則是修改時要重新REBULE的工程較大。
此連結有Angular所有支援的語系:Angular repository
在angular5的地區設定是使用BCP47,這個規格隨著時間而有些微改變如下:
LOCALE NAME | OLD LOCALE ID | NEW LOCALE ID |
---|---|---|
Indonesian | in | id |
Hebrew | iw | he |
Romanian Moldova | mo | ro-MD |
Norwegian Bokmål | no, no-NO | nb |
Serbian Latin | sh | sr-Latn |
Filipino | tl | fil |
Portuguese Brazil | pt-BR | pt |
Chinese Simplified | zh-cn, zh-Hans-CN | zh-Hans |
Chinese Traditional | zh-tw, zh-Hant-TW | zh-Hant |
Chinese Traditional Hong Kong | zh-hk | zh-Hant-HK |
預設所有管道如DatePipe,CurrencyPipe,DecimalPipe 和PercentPipe所使用語言環境的數據格式都是en-US
,如果要設置為其他語言環境,則需要導入該新語言環境的語言環境數據。
利用CLI的--locale
會自動為我們設置這部份,若要手動設置方法如下:
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
// the second parameter 'fr' is optional
registerLocaleData(localeFr, 'fr');
在angular內,設定多語系檔案的順序如下:
開發於template先使用預設的語言做開發,如:
<h1>Hello i18n!</h1></pre>
增加i18n的標記,如:
<h1 i18n>Hello i18n!</h1></pre>
利用CLI產生messages.xlf
,如下:
ng xi18n
將完成的翻譯文件合併到應用程式中:
ng serve --aot --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr
為了使翻議者能夠更準確的翻議,可以在i18n的指令裡面增加上下文說明,如:
<h1 i18n="An introduction header for this sample">Hello i18n!</h1>
如果相同的文字需要有不同的翻議,則可增加meaning
的設定。其格式為meaning|description
,如:
<h1 i18n="site header|An introduction header for this sample">Hello i18n!</h1>
若有相同翻議字串但meaning不同,則會有不同的翻譯。若翻議字串相同,description不同,則依然是相同的翻議。
除了使用meaning以外,也可以自己定義一個翻議字串的ID來使用,如:
<h1 i18n="@@introductionHeader">Hello i18n!</h1>
假如兩個翻議字串不同卻取了相同的ID,會造成翻譯後有著相同的字串:
<h3 i18n="@@myId">Hello</h3>
<p i18n="@@myId">Good bye</p>
翻譯檔案內容如下:
<trans-unit id="myId" datatype="html">
<source>Hello</source>
<target state="new">Bonjour</target>
</trans-unit>
則生成的HTML內容如下:
<h3>Bonjour</h3>
<p>Bonjour</p>
如果有時候只是想要翻譯文字而不想使用任何HTML TAG,則可以使用ng-container
<ng-container i18n>I don't output any element</ng-container>
假如有一個像下面的圖片有著純文字的替代文字
<img [src]="logo" title="Angular logo">
可以使用這樣的tag來做i18n的設定
<img [src]="logo" i18n-title title="Angular logo" />
這種技術適用於任何元素的任何屬性。
使用i18n-x="<meaning>|<description>@@"
語法來指定含義,說明和標識。
在一些語言的狀況下,不同的數量使用的詞彙不一樣,例如時間,可以顯示"just now", "one minute ago"或"x minutes ago" 這時候可以用這樣的方式來設定翻譯文字
<span i18n>Updated {minutes, plural, =0 {just now} =1 {one minute ago} other {{{minutes}} minutes ago}}</span>
上面第一個參數minutes是最重要的,用來設定這個字串要放入的變數
第二個參數plural為翻譯類型(請參見:ICU Message Format)
第三個參數則是設定各種數字要顯示的文字
第三個參數可設定的選項有下面這些:
也可以根據要顯示的變數內容來顯示不同的翻譯字串
<span i18n>The author is {gender, select, m {male} f {female} o {other}}</span>
使用CLI打入可產生messages.xlf
的翻譯原檔,預設是產生xlf檔案
ng xi18n
如果想要產出其他類型檔案可以加上--i18nFormat
的參數如下:
ng xi18n --i18nFormat=xlf
ng xi18n --i18nFormat=xlf2
ng xi18n --i18nFormat=xmb
接著把messages.xlf改名為messages.fr.xlf(假使要翻譯的目標語言為fr) 下面為一個產出的xlf檔案內容的範例:
<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>
target
裡面要填的就是目標翻譯語言要顯示的文字
使用下面三個參數:
--i18nFile
: 翻譯檔案的位置--i18nFormat
: 翻譯檔案的格式--locale
: 被翻譯的語系名稱ng serve --aot --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr
在src/main.ts
裡設定所使用的語系
import { enableProdMode, TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
// use the require method provided by webpack
declare const require;
// we use the webpack raw-loader to return the content as a string
const translations = require(`raw-loader!./locale/messages.fr.xlf`);
platformBrowserDynamic().bootstrapModule(AppModule, {
providers: [
{provide: TRANSLATIONS, useValue: translations},
{provide: TRANSLATIONS_FORMAT, useValue: 'xlf'}
]
});
在src/app/app.module.ts
裡加上LOCALE_ID
import { LOCALE_ID, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from '../src/app/app.component';
@NgModule({
imports: [ BrowserModule ],
declarations: [ AppComponent ],
providers: [ { provide: LOCALE_ID, useValue: 'fr' } ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
如果介面想要提供繁體, 簡體以及英文三種語系切換該如何實現?
感謝你的回覆. 不過該文是透過 http 抓取語系檔再搭配 pipe 實現多語系. 這表示 Angular i18n 無法實現動態多語系效果?
https://blog.johnwu.cc/article/angular-4-localization.html
可以的,這邊有動態多語系的範例
謝謝你的回應, 可能我的問題問的不是很好. 因為我是按照這篇教學來練習 x18n 套件來實現多語系, x18n 使用 .xlf 檔來實做語系並且在編譯時將 .xlf 打包進 .js, 所以 我的理解是這個方法會導致每個語系要打包一次, 但共用邏輯不就重複打包?
透過動態載入語系包的作法是可以達成多語系無誤, 不過好像就沒辦法使用 x18n 套件, 這樣看來 x18n 套件似乎實用性不高. 以上是我的理解
請問有能自動檢查語系檔遺漏的工具嗎