語言包結構設計html
1.目錄結構設計前端
common langgit
server side lang - 與後臺共用的部分github
front end side lang - 前端通用的部分npm
feature langjson
foundgulp
found.zh-cn.json - 發現模塊 - 簡體中文語言包數組
found.zh-tw.json - 發現模塊 - 繁體中文(臺灣)語言包app
found.zh-hk.json - 發現模塊 - 繁體中文(香港)語言包ionic
found.en-ww.json - 發現模塊 - 英文(全球)語言包
found.en-us.json - 發現模塊 - 英文(美國)語言包
2.語言包內部結構設計
common
// zh-cn.json { "TITLE": "歡迎使用APP", "HOME": "首頁", "LEARN": "學習", "FOUND": "發現", "MY": "個人", "CANCEL": "取消", "OK": "確認" } // en-ww.json { "TITLE": "Welcome To APP", "HOME": "HOME", "LEARN": "LEARN", "FOUND": "FOUND", "MY": "MY", "CANCEL": "CANCEL", "OK": "OK" }
feature
// found.zh-cn.json { "FOUND_PRE_POST_MSG": "帖子正在提交中" 或 "{{content}}正在提交中" - content: 帖子或評論 } // found.en-ww.json { "FOUND_PRE_POST_MSG": "It is submitting." }
實現方案
利用已有的 ng2-translate 庫實現多語言切換功能。
使用示例:
1.安裝 ng2-translate
npm install ng2-translate --save
2.在 app.module.ts 中添加如下代碼
import { Http } from '@angular/http'; import { TranslateModule, TranslateStaticLoader, TranslateLoader } from 'ng2-translate/ng2-translate'; export function createTranslateLoader(http: Http) { return new TranslateStaticLoader(http, './assets/i18n', '.json'); } @NgModule({ imports: [ TranslateModule.forRoot({ provide: TranslateLoader, useFactory: (createTranslateLoader), deps: [Http] }) ] })
3.在 src/assets/i18n 目錄下添加語言包,如 en-ww.json 和 zh-cn.json 文件
3.1 en-ww.json
{ "TITLE": "Welcome To APP", "HINT": "Select your language", "HOME": "HOME", "LEARN": "LEARN", "FOUND": "FOUND", "MY": "MY", "CANCEL": "CANCEL", "OK": "OK" }
3.2 zh-cn.json
{ "TITLE": "歡迎使用APP", "HINT": "請選擇語言", "HOME": "首頁", "LEARN": "學習", "FOUND": "發現", "MY": "個人", "CANCEL": "取消", "OK": "確認" }
4.ng2-translate應用
4.1 TranslatePipe
<ion-title> {{ 'HELLO' | translate:param }} </ion-title> param = {value: 'Dayana'};
4.2 TranslateService
import {TranslateService} from 'ng2-translate'; constructor(translate: TranslateService) { // 設置默認的語言包 translate.setDefaultLang('en'); // 切換語言包 translate.use('en'); } translate.get('HELLO', {value: 'Dayana'}).subscribe((res: string) => { console.log(res); //=> 'Hello Dayana' });
4.3 TranslateDirective
<div [translate]="'HELLO'" [translateParams]="{value: 'Dayana'}"></div> 或 <div translate [translateParams]="{value: 'Dayana'}">HELLO</div>
5.示例
<ion-tabs> <ion-tab [root]="tab1Root" [tabTitle]="('HOME' | translate)" tabIcon="home"> </ion-tab> <ion-tab [root]="tab2Root" [tabTitle]="('LEARN' | translate)" tabIcon="information-circle"> </ion-tab> <ion-tab [root]="tab3Root" [tabTitle]="('FOUND' | translate)" tabIcon="contacts"> </ion-tab> </ion-tabs>
打包方案
利用 npm scripts 提供的鉤子,在運行 serve 或 build 任務前,合併各個目錄下的語言包,統一輸出至 src/assets/i18n 目錄下。在開發階段能夠運行 npm run dev ,經過已註冊的鉤子 predev: gulp generate-lang-json,即調用 gulp generate-lang-json 任務生成語言包。
具體實現:
/** * 合併各個子目錄下的語言包文件,生成獨立的語言包 */ var langJson = {}; gulp.task('generate-lang-json', function () { return gulp.src(['src/**/*' + i18nLang + '.json', '!src/assets/**/*.json']) .pipe(through2.obj(function (file, encoding, callback) { var originalContents = String(file.contents); var subLangJson; try { subLangJson = JSON.parse(originalContents); for (key in subLangJson) { if(langJson[key]){ throw new Error('The key \''+langJson[key] +' \'is repeat,file path:'+file.history); }else{ langJson[key] = subLangJson[key] } } } catch (e) { console.dir(e); throw new Error('Parse language file path failed'); } file.contents = new Buffer(JSON.stringify(langJson)); callback(null, file); })) .pipe(rename(i18nLang + '.json')) .pipe(gulp.dest('src/assets/i18n/')) });
舊版本數據處理
公司現有的系統是採用 ionic 1.x 的版本開發,近期已經開始進行 ionic 2.x 的升級工做。所以須要抽取現有系統中的靜態文本,而後對已有的文本進行分類。好比分爲通用消息、功能模塊內的消息。下面主要介紹一下,文本採集和處理思路。
使用正則匹配項目的JS文件(模板和業務邏輯文件)
對採集的文本進行去重處理
轉成JavaScript對象,如代碼段一
調用百度或其餘翻譯的API進行英文翻譯,如代碼段二
轉換成標準的語言包
代碼段一
{ "簽到表": "簽到表", "講師名單": "講師名單", "助教名單": "助教名單", "所有評價": "所有評價", "線下課程詳情": "線下課程詳情", "培訓地址": "培訓地址", "所有培訓": "所有培訓", "混合培訓": "混合培訓", "線下培訓": "線下培訓", "在線培訓": "在線培訓", "報名中": "報名中", "預報名": "預報名" }
代碼段二
{ '簽到表': 'Attendance list', '講師名單': 'lecturers', '助教名單': 'Teaching assistant list', '所有評價': 'All evaluation', '線下課程詳情': 'Online course details', '培訓地址': 'Training address', '所有培訓': 'All training', '混合培訓': 'Mixed training', '線下培訓': 'Offline training', '在線培訓': 'Online training', '報名中': 'Enrollment', '預報名': 'Forecast name' }
語言包字段查詢功能
爲了方便地查詢語言包中已定義的字段或字段值,咱們實現了一個簡單的查詢功能,具體代碼以下:
tools.html
<ion-header> <ion-navbar> <ion-title>tools</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-searchbar (ionInput)="filterItems($event)" (ionClear)="reset()"></ion-searchbar> <ion-grid> <ion-row *ngFor="let item of items"> <ion-col width-100>{{item}}</ion-col> </ion-row> </ion-grid> </ion-content>
tools.ts
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import { Http } from '@angular/http'; @Component({ selector: 'page-tools', templateUrl: 'tools.html' }) export class ToolsPage { constructor( public navCtrl: NavController, public navParams: NavParams, public http: Http) { } _originItems: Array<string>; // 保存轉化後的原始數據 items: Array<string>; // 頁面上列表的數據源 ionViewDidLoad() { this.http.get(`assets/i18n/zh-cn.json`) .map(res => res.json()) .subscribe(res => { this.items = this._originItems = this.transformItem(res); }); } /** * 轉換語言包JSON對象 * {key: value}對象轉換爲'key - value'數組 */ transformItem(originItems: Array<any>) { let items = []; for (let key in originItems) { items.push(`${key} - ${originItems[key]}`); } return items; } /** * 搜索過濾 */ filterItems(ev: any) { let val = ev.target.value; if (val && val.trim() != '') { val = (<string>val).toUpperCase(); this.items = this._originItems.filter((item) => { return item.indexOf(val) > -1; }); } else { this.reset(); } } /** * 重置列表 */ reset() { this.items = this._originItems; } }
參考文檔