Angular i18n可做到的事
- 以本地格式顯示日期,數量,百分比和貨幣。
- 在組件模板中翻譯文字。
- 翻譯單數和複數
- 翻譯HTML屬性的替代文字
可以透過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');
template內的多語系支援
在angular內,設定多語系檔案的順序如下:
- 開發於template先使用預設的語言做開發,如:
<h1>Hello i18n!</h1>
- 增加i18n的標記,如:
<h1 i18n>Hello i18n!</h1>
- 利用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>
翻譯HTML屬性的替代文字
假如有一個像下面的圖片有著純文字的替代文字
<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)
第三個參數則是設定各種數字要顯示的文字
第三個參數可設定的選項有下面這些:
- =0 (or any other number)
- zero
- one
- two
- few
- many
- other
也可以根據要顯示的變數內容來顯示不同的翻譯字串
<span i18n>The author is {gender, select, m {male} f {female} o {other}}</span>
利用ng xi18n來產生翻譯原檔
使用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
裡面要填的就是目標翻譯語言要顯示的文字
合併翻譯檔案回應用程式裡
使用AOT的方式
使用下面三個參數:
--i18nFile
: 翻譯檔案的位置--i18nFormat
: 翻譯檔案的格式--locale
: 被翻譯的語系名稱
ng serve –aot –i18nFile=src/locale/messages.fr.xlf –i18nFormat=xlf –locale=fr
使用JIT的方式
在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 { }
參考資料
- Internationalization (i18n)
- angular2 學習筆記 ( translate, i18n 翻譯 )
- 使用Angular-CLI发布一个i18n(国际化)应用(译)
- [MAN鐵人賽]Day 14:AngularJS – Localization
- Angular2中使用ngx-translate进行国际化:使用ngx-translate來做多語系
- [Angular2] 在專案加入多國語系:使用ng2-translate來整合i18n模組