摘要:正如官網所說,項目國際化是一件具有挑戰(zhàn)性,需要多方面的努力持久的奉獻和決心的任務。本文將介紹項目的國際化方案,涉及靜態(tài)文件和文件文案的國際化。參考目錄的國際化在線例子國際化
正如angular官網所說,項目國際化是一件具有挑戰(zhàn)性,需要多方面的努力、持久的奉獻和決心的任務。
本文將介紹angular項目的國際化方案,涉及靜態(tài)文件(html)和ts文件文案的國際化。
Angular: 5.0
Angular Cli: 1.6.1(1.5.x也可以)
NG-ZORRO: 0.6.8
Angular i18ni18n模板翻譯流程有四個階段:
在組件模板中標記需要翻譯的靜態(tài)文本信息(即打上i18n標簽)。
Angular的i18n工具將標記的信息提取到一個行業(yè)標準的翻譯源文件(如.xlf文件,使用ng xi18n)。
翻譯人員編輯該文件,翻譯提取出來的文本信息到目標語言,并將該文件還給你(需要翻譯人員接入,本文采用將xlf文件轉為json格式文件輸出,最終將json文件轉換回xlf格式文件)。
Angular編譯器導入完成翻譯的文件,使用翻譯的文本替換原始信息,并生成新的目標語言版本的應用程序。
你可以為每種支持的語言構建和部署多帶帶的項目版本,僅需替換翻譯后的xlf文件即可。
如何在模板文件中使用?
i18n提供了幾種使用方式,還專門為單復數提供了翻譯方式(個人沒有使用,感覺不太方便)。接下來以一個多帶帶的html文件來介紹幾種使用方法。
Angular i18n Angular 國際化項目
國際化是一項很具有挑戰(zhàn)性,需要多方面的努力、持久的奉獻和決心的任務。
讓我們現在開始吧! 朋友!
上述代碼展示了幾種i18n的使用方式:
1、使用i18n屬性標記(可添加上說明性文案,格式如:title|description@@id,title和description可幫助翻譯人員更好地理解文案含義,是否添加取決于自身項目情況)
可以在靜態(tài)標簽上直接打上i18n的tag,如 生成的xlf(xml)字段格式為xxx.ts linenum
2、為title添加i18n屬性
對于html標簽屬性,同樣可以添加i18n,如 生成的xlf(xml)格式同上
3、翻譯文本,而不必創(chuàng)建元素
我們有時候會出現一句話多個斷句情況,如果每次都添加span、label這些元素包裹的話,可能嚴重影響頁面布局,這時候我們可以使用ng-container來包裹需要翻譯的文案。在頁面顯示為
讓我們現在開始吧! 朋友!LET"S GO朋友!
* ng-container變?yōu)榱俗⑨寜K,這樣做不會影響頁面布局(尤其是應用了style樣式的情況)
打上標簽后,我們只要執(zhí)行ng xi18n即可自動創(chuàng)建出xlf文件,通常為message.xlf,如需自定義,可自行前往 Angular CLI 官網查看。
XLF與JSON轉換xlf轉json方法
我個人是采用xml2js庫進行操作,簡單代碼如下: const fs = require("fs"); xml2js = require("xml2js"); var parser = new xml2js.Parser(); fs.readFile(fileName, "utf8", (err, data) => { parser.parseString(data, function (err, result) { // 讀取新文件全部需要翻譯的數據,并對比已翻譯的進行取舍,具體轉換成的格式結構可自行查看 result["xliff"]["file"][0]["body"][0]["trans-unit"].forEach((item) => { var itemFormat = { "key" : item["$"]["id"], "value": item["source"][0] }; // 執(zhí)行相關操作,key-value形式是為了統(tǒng)一翻譯文件結構,可按需定義 }) }); });
json轉xlf方法
function backToXLF(translatedParams) { // 文件格式可自行參考angular.cn官網的例子 var xlfFormat = { "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": [] } ] } ] } }; if (translatedParams instanceof Array) { // 獲取原始名稱 translatedParams.forEach((data) => { var tmp = { "$" : { "id" : data.key, "datatype": "html" }, "source": [i18nItemsOrigin[data.key]], // 這里的i18nItemsOrigin是json格式,屬性名為key值,表示原始文案 "target": [data.value] }; // 數組,json項 xlfFormat["xliff"]["file"][0]["body"][0]["trans-unit"].push(tmp); }); } var builder = new xml2js.Builder(); var xml = builder.buildObject(xlfFormat); return xml; } 這樣提取文案信息和轉換翻譯后的文件就完成了,接下來我們需要把翻譯好的文案應用到項目中去。部署翻譯文件
JIT模式
src目錄下新建locale文件夾,將翻譯轉換后的demo.en-US.xlf文件存在改目錄下
app文件夾下新建i18n-providers.ts
import { LOCALE_ID, MissingTranslationStrategy, StaticProvider, TRANSLATIONS, TRANSLATIONS_FORMAT } from "@angular/core"; import { CompilerConfig } from "@angular/compiler"; import { Observable } from "rxjs/Observable"; import { LOCALE_LANGUAGE } from "./app.config"; // 自行定義配置位置 export function getTranslationProviders(): Promise{ // get the locale string from the document const locale = LOCALE_LANGUAGE.toString(); // return no providers const noProviders: StaticProvider[] = []; // no locale or zh-CN: no translation providers if (!locale || locale === "zh-CN") { return Promise.resolve(noProviders); } // Ex: "locale/demo.zh-MO.xlf` const translationFile = `./locale/demo.${locale}.xlf`; return getTranslationsWithSystemJs(translationFile) .then((translations: string) => [ { provide: TRANSLATIONS, useValue: translations }, { provide: TRANSLATIONS_FORMAT, useValue: "xlf" }, { provide: LOCALE_ID, useValue: locale }, { provide: CompilerConfig, useValue: new CompilerConfig({ missingTranslation: MissingTranslationStrategy.Error }) } ]).catch(() => noProviders); // ignore if file not found } declare var System: any; // 獲取locale文件 function getTranslationsWithSystemJs(file: string) { let text = ""; const fileRequest = new XMLHttpRequest(); fileRequest.open("GET", file, false); fileRequest.onerror = function (err) { console.log(err); }; fileRequest.onreadystatechange = function () { if (fileRequest.readyState === 4) { if (fileRequest.status === 200 || fileRequest.status === 0) { text = fileRequest.responseText; } } }; fileRequest.send(); const observable = Observable.of(text); const prom = observable.toPromise(); return prom; }
main.ts文件修改為
import { enableProdMode } from "@angular/core"; import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; import { AppModule } from "./app/app.module"; import { environment } from "./environments/environment"; import { getTranslationProviders } from "./app/i18n-providers"; if (environment.production) { enableProdMode(); } getTranslationProviders().then(providers => { const options = { providers }; platformBrowserDynamic().bootstrapModule(AppModule, options) .catch(err => console.log(err)); });
別忘了將locale目錄添加到.angular-cli.json里,來多帶帶打包。
AOT模式(推薦)
對于AOT模式打包的持續(xù)來說,不需要上述復雜的配置,只需要在原有build基礎上,加上相應的i18n文件即可,如:
ng build --prod --build-optimizer -bh / --i18n-format=xlf --locale=en --i18n-file=./src/locale/demo.en-US.xlf
這樣打出的包會自動將翻譯文件應用到項目中。
這樣我們對靜態(tài)文案的翻譯工作基本已經完成了,但是有些動態(tài)文案如ts文件里的文案或者第三方框架屬性該如何翻譯呢?下面會介紹針對 ts 文件和 NG-ZORRO 框架實現動態(tài)文案翻譯的方案。
ts文件文案和NG-ZORRO框架文案翻譯具體思路
通過Pipe調用Service方法,根據對應的唯一id值匹配json對象里的翻譯結果,進而返回渲染到前端,參考于NG-ZORRO框架的國際化實現方案。
首先我們定義一下json翻譯對象的格式,全部為三層結構,動態(tài)變量需要按%%包裹,這樣做的原因是和項目結構相關聯,也便于后期和i18n方式格式統(tǒng)一。
{ "app": { "base": { "hello": "文件文案", "userCount": "一共%num%人" } } }
格式已定,我們繼續(xù)定義Service處理方式
這里復用 NG-ZORRO的國際化方案 ,可以簡化我們的開發(fā),有興趣的可以參看一下其源碼。
*** TranslateService *** import { Injectable } from "@angular/core"; // 引入語言配置和國際化文件文案對象 import { LOCALE_LANGUAGE } from "../app.config"; import { enUS } from "../locales/demo.en-US"; import { zhCN } from "../locales/stream.zh-CN"; @Injectable() export class TranslateService { private _locale = LOCALE_LANGUAGE.toString() === "zh-CN" ? zhCN : enUS; constructor() { } // path為app.base.hello格式的字符串,這里按json層級取匹配改變量 translate(path: string, data?: any): string { let content = this._getObjectPath(this._locale, path) as string; if (typeof content === "string") { if (data) { Object.keys(data).forEach((key) => content = content.replace(new RegExp(`%${key}%`, "g"), data[key])); } return content; } return path; } private _getObjectPath(obj: object, path: string): string | object { let res = obj; const paths = path.split("."); const depth = paths.length; let index = 0; while (res && index < depth) { res = res[paths[index++]]; } return index === depth ? res : null; } }
這樣,只需要在Pipe中調用Service的translate方法即可
*** NzTranslateLocalePipe *** import { Pipe, PipeTransform } from "@angular/core"; import { TranslateService } from "../services/translate.service"; @Pipe({ name: "nzTranslateLocale" }) export class NzTranslateLocalePipe implements PipeTransform { constructor(private _locale: TranslateService) { } transform(path: string, keyValue?: object): string { return this._locale.translate(path, keyValue); } }
好了,現在我們處理邏輯已經完全結束了,下面介紹一下如何使用
*** NG-ZORRO 控件 ***// 無動態(tài)參數 ... // 有動態(tài)參數 *** ts文件 *** export class AppComponent implements OnInit { demoTitle=""; users = ["Jack", "Johnson", "Lucy"]; constructor(privete translateService: TranslateService) { } ngOnInit() { this.demoTitle = this.translateService.translate("app.base.hello"); } }
以上流程基本上能滿足大部分angular項目的國際化需求,如果需要更加復雜的國際化情況,歡迎討論。
總結Angular到5.0的國際化已經相對來說簡便了很多,我們只需要在合適的地方打上i18n的tag即可方便快速地提取需要翻譯文案,具體如何處理翻譯后的文件因人而異,多種方法可幫助我們轉換(如本文通過nodejs)。
復雜一點的是無法通過打i18n標簽來翻譯的文本,NG-ZORRO的國際化方案彌補了這方面的不足,結合起來可以很方便地完成項目的國際化。 國際化如果沒有專門的團隊支持,翻譯難度很大,需要考慮的東西很多,比如繁體還有澳門繁體、臺灣繁體等,語法也不盡相同。
參考目錄
Angular的國際化(i18n)在線例子
NG-ZORRO Locale 國際化
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/90691.html
摘要:關于的,網上的資料也不多,剛好項目需要用到,就自己去查閱各種資料,自己整理了出來,分享下出來給大家吧。 關于angular2的i18n,網上的資料也不多,剛好項目需要用到,就自己去查閱各種資料,自己整理了出來,分享下出來給大家吧。廢話不多說!直接上代碼: 首先我們肯定要新建一個文件,叫aaa(網上angular-cli教程很多),cmd打開命令進入到隨便一個目錄底下: ng new a...
摘要:關于的,網上的資料也不多,剛好項目需要用到,就自己去查閱各種資料,自己整理了出來,分享下出來給大家吧。 關于angular2的i18n,網上的資料也不多,剛好項目需要用到,就自己去查閱各種資料,自己整理了出來,分享下出來給大家吧。廢話不多說!直接上代碼: 首先我們肯定要新建一個文件,叫aaa(網上angular-cli教程很多),cmd打開命令進入到隨便一個目錄底下: ng new a...
摘要:以下簡單介紹的重大變化。狀態(tài)轉交及對的支持這樣更便于在服務端和客戶之間共享應用狀態(tài)。狀態(tài)轉交的相關文檔幾周后會發(fā)布。我們刪除很多以前廢棄的如,也公布了一些新的廢棄項。以上指南會詳細介紹這些變更。已知問題當前已知與相關的問題。 我們很高興地宣布Angular 5.0.0——五角形甜甜圈發(fā)布啦!這又是一個主版本,包含新功能并修復了很多bug。它再次體現了我們把Angular做得更小、更快、...
閱讀 569·2023-04-26 02:59
閱讀 700·2023-04-25 16:02
閱讀 2171·2021-08-05 09:55
閱讀 3585·2019-08-30 15:55
閱讀 4680·2019-08-30 15:44
閱讀 1809·2019-08-30 13:02
閱讀 2207·2019-08-29 16:57
閱讀 2296·2019-08-26 13:35