Angular i18n 的官方作法並不讓人滿意,我後來找到 ngx-translate
先說明一下他的作法,他把這些翻譯好的字詞放到 JSON 翻譯檔去,在執行時就可以透過 http client 去拉取回來作動態的替換。
好處是,程式只要建置一次,不需要針對個別語言再次建置,網頁伺服器那邊也不需要特別寫設定去處理,而且可以做到動態切換語言。壞處是會有額外的 HTTP 請求,會增加流量。
ngx-translate 額外好的地方是,他提供了相應的工具、plugin,相當的方便。
那麼怎麼使用呢?我推薦看這篇【Angular】ngx-translate 多語系實務應用 ,他這篇的缺點是萃取字串的部分是手動,我建議萃取字串的部分可以用原作者 biesbjerg 的 ngx-translate-extract ,就不用自己找字串找的太累。
先進行安裝
npm install @ngx-translate/core —save npm install @ngx-translate/http-loader --save
然後改 app.module.ts
import { TranslateModule, TranslateLoader, TranslateCompiler } from '@ngx-translate/core'; import { TranslateHttpLoader } from '@ngx-translate/http-loader'; import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler'; import { HttpClientModule, HttpClient } from '@angular/common/http'; // … 省略 … // 這主要是告訴 ngx-translate 翻譯檔該怎麼載入,用 TranslateHttpLoader 是表示以 HTTP 方式去下載、載入 export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, './assets/i18n/', '.json'); } // … 省略 … // 設定 const translateConfig = { defaultLanguage: 'en-US', // 預設是英文 loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, // 前面寫的 Factory deps: [HttpClient] }, compiler: { provide: TranslateCompiler, useClass: TranslateMessageFormatCompiler } }; @NgModule({ // … imports: [ BrowserAnimationsModule, BrowserModule, TranslateModule.forRoot(translateConfig), // 模組帶設定 // … ], // … })
在 HTML 裡,使用
// 方法 1 {{ ‘your_translation_key’ | translate }} // 方法 2 <div [translate]=“‘your_translation_key’”></div> // 方法 3,適用於字串要用 HTML <div [innerHTML]="'HELLO' | translate"></div>
他還可以帶參數,只是這邊我看不太懂,暫時也還用不到。
在程式裡,使用
// 先匯入 import {TranslateService} from '@ngx-translate/core'; import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker'; // … 省略 … export class AppComponent implements OnInit { l10n__title = ''; constructor(public translate: TranslateService) { } ngOnInit(): void { const self = this; // 讓 ngx-translate-extract 可以抓到字串用的 _('your_translation_key'); // 取得字串都要使用 translate.get() 來預先取得 this.translate.get('your_translation_key').subscribe((res: string) => { self.l10n__title = res; }); } }
這裡要特別說明一點,也是我當初用的時候搞錯的地方,就是上面用到的 your_translation_key 並不是字串,而是你自定義的代碼,裡面有使用 ‘.’ 的時候,在產出的 JSON 裡會變成 nested object ,舉個例子,假設這個 key 是 login.title,那麼 JSON 翻譯檔就會是
{ "login": { "title": "" } }
接下來講 ngx-translate-extract,ngx-translate-extract 的安裝
npm install @biesbjerg/ngx-translate-extract --save-dev
裝好以後,在 package.json 的 scripts 裡加入 (要產生什麼語言,請替換 {en,da,de,fi,nb,nl,sv} 這個字串,以繁體中文來說,是zh-TW或zh-Hant,只有英文跟繁體中文的話,就放 {en-US,zh-TW}。 )
// package.json ... "scripts": { "i18n:init": "ngx-translate-extract --input ./src --output ./src/assets/i18n/template.json --key-as-default-value --replace --format json", "i18n:extract": "ngx-translate-extract --input ./src --output ./src/assets/i18n/{en,da,de,fi,nb,nl,sv}.json --clean --format json" } ...
然後建立存放字串的資料夾:mkdir -p src/assets/i18n,執行 npm run i18n:extract 以後,就可以在 src/assets/i18n 裡看到翻譯檔了。
沒有留言:
張貼留言