[Angular] i18n由淺入深

大綱

一個要提供給國際使用的網站,一定會遇到多國語系的問題,Angular已經幫我們想好解決方案,i18n,一起進入這個世界探索吧!

入門

多國語系是網頁必定會遇到的問題,在開始之前,我們先來看一下預期的目標
translate

我們希望畫面上的字能根據語系來做相對應的呈現
i18n!!!粉墨登場

首先要在component中加上i18n這個directive

1
<h1 i18n>Hello world</h1>

接著我們要取得檔案,來維護內容,執行這段指令,將檔案放到src底下的locale這個目錄中

ng xi18n –output-path src/locale

messages.xlf

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="ng2.template">
<body>
<trans-unit id="5816217f424111ae4c91dd72ee1db0ae252763b5" datatype="html">
<source>Hello World!</source>
<target>世界你好!</target>
</trans-unit>
</body>
</file>
</xliff>

得到產生的檔案後,就可以來實驗看看囉,執行下面的指令

ng serve –aot –i18n-file=src/locale/messages.xlf –locale=en –i18n-format=xlf

就可以發現到剛剛的Hello World!被替換成世界你好!

試著用建立另一個語言檔看看

進階

讓我們換個指令,來輸出成檔案看看他的運作模式

ng build –prod –i18n-file=src/locale/messages.zh-TW.xlf –locale=zh-TW –i18n-format=xlf

build

可以發現到,其實他是直接把html的內容給替換掉了!
那這樣是不是說,要產生不同語系,就必須重新編譯一次…!?

這樣的作法不可能應用到網站中,因此我們需要改變一下
如果只要架一個網站,就要想辦法將檔案動態載入

首先使用system.import的方式載入檔案,並且載入要在bootstrap之前
所以我們可以來看看下面這段,先用固定的語系

接著要在main.ts中載入進來,可以看到的是先把由上面先把檔案載入後,再來bootstrap

但上面我們是用固定的語系,接著我們要做的事情就是動態的語系
這邊使用的方法是在網址列加上語系
切換下拉選單時,就讓網頁整個重新載入

app.component.html

1
2
3
4
<select (ngModelChange)="changeLocale($event)" [(ngModel)]="locale">
<option value="en">English</option>
<option value="zh-tw">中文</option>
</select>

app.component.ts

1
2
3
changeLocale(event: string) {
window.location.href = `/${event}/`;
}

那我們就可以在getTranslationProviders這個裡面,去解析網址,來取得目前的語系

這時候我們就可以下拉選單來切換語系了!
i18n demo

參考

Angular i18n introduction
Deploying an i18n Angular app with angular-cli
Angular 2 internationalization explained: i18n + Angular CLI + AOT
Lost in Translation - Oliver Combe @ ng-confg 2017