angular2-ionic2 icon indicating copy to clipboard operation
angular2-ionic2 copied to clipboard

Ionic 2 i18n 方案设计

Open semlinker opened this issue 7 years ago • 0 comments

语言包结构设计

1.目录结构设计

  • common lang
    • server side lang - 与后台共用的部分
    • front end side lang - 前端通用的部分
  • feature lang
    • found
      • found.zh-cn.json - 发现模块 - 简体中文语言包
      • found.zh-tw.json - 发现模块 - 繁体中文(台湾)语言包
      • found.zh-hk.json - 发现模块 - 繁体中文(香港)语言包
      • found.en-ww.json - 发现模块 - 英文(全球)语言包
      • found.en-us.json - 发现模块 - 英文(美国)语言包

2.语言包内部结构设计

  • common

    // zh-cn.json { "TITLE": "欢迎使用职行力", "HOME": "首页", "LEARN": "学习", "FOUND": "发现", "MY": "我的", "CANCEL": "取消", "OK": "确认" }

    // en-ww.json { "TITLE": "Welcome To EXE 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 EXE APP",
  "HINT": "Select your language",
  "HOME": "HOME",
  "LEARN": "LEARN",
  "FOUND": "FOUND",
  "MY": "MY",
  "CANCEL": "CANCEL",
  "OK": "OK"
}

3.2 zh-cn.json

{
    "TITLE": "欢迎使用职行力",
    "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 的升级工作。因此需要抽取现有系统中的静态文本,然后对已有的文本进行分类。比如分为通用消息、功能模块内的消息。下面主要介绍一下,文本采集和处理思路。

  1. 使用正则匹配项目的JS文件(模板和业务逻辑文件)
  2. 对采集的文本进行去重处理
  3. 转成JavaScript对象,如代码段一
  4. 调用百度或其他翻译的API进行英文翻译,如代码段二
  5. 转换成标准的语言包

代码段一

{
  "签到表": "签到表",
  "讲师名单": "讲师名单",
  "助教名单": "助教名单",
  "全部评价": "全部评价",
  "线下课程详情": "线下课程详情",
  "培训地址": "培训地址",
  "全部培训": "全部培训",
  "混合培训": "混合培训",
  "线下培训": "线下培训",
  "在线培训": "在线培训",
  "报名中": "报名中",
  "预报名": "预报名"
}

代码段二

{
  '签到表': 'Attendance list',
  '讲师名单': 'lecturers',
  '助教名单': 'Teaching assistant list',
  '全部评价': 'All evaluation',
  '线下课程详情': 'Online course details',
  '培训地址': 'Training address',
  '全部培训': 'All training',
  '混合培训': 'Mixed training',
  '线下培训': 'Offline training',
  '在线培训': 'Online training',
  '报名中': 'Enrollment',
  '预报名': 'Forecast name'
}

参考资料

1.国家/地区 语言缩写代码

国家/地区 语言代码 国家/地区 语言代码 简体中文(中国) zh-cn 繁体中文(台湾地区) zh-tw 繁体中文(香港) zh-hk 英语(香港) en-hk 英语(美国) en-us 英语(英国) en-gb 英语(全球) en-ww 英语(加拿大) en-ca 英语(澳大利亚) en-au 英语(爱尔兰) en-ie 英语(芬兰) en-fi 芬兰语(芬兰) fi-fi 英语(丹麦) en-dk 丹麦语(丹麦) da-dk 英语(以色列) en-il 希伯来语(以色列) he-il 英语(南非) en-za 英语(印度) en-in 英语(挪威) en-no 英语(新加坡) en-sg 英语(新西兰) en-nz 英语(印度尼西亚) en-id 英语(菲律宾) en-ph 英语(泰国) en-th 英语(马来西亚) en-my 英语(阿拉伯) en-xa 韩文(韩国) ko-kr 日语(日本) ja-jp 荷兰语(荷兰) nl-nl 荷兰语(比利时) nl-be 葡萄牙语(葡萄牙) pt-pt 葡萄牙语(巴西) pt-br 法语(法国) fr-fr 法语(卢森堡) fr-lu 法语(瑞士) fr-ch 法语(比利时) fr-be 法语(加拿大) fr-ca 西班牙语(拉丁美洲) es-la 西班牙语(西班牙) es-es 西班牙语(阿根廷) es-ar 西班牙语(美国) es-us 西班牙语(墨西哥) es-mx 西班牙语(哥伦比亚) es-co 西班牙语(波多黎各) es-pr 德语(德国) de-de 德语(奥地利) de-at 德语(瑞士) de-ch 俄语(俄罗斯) ru-ru 意大利语(意大利) it-it 希腊语(希腊) el-gr 挪威语(挪威) no-no 匈牙利语(匈牙利) hu-hu 土耳其语(土耳其) tr-tr 捷克语(捷克共和国) cs-cz 斯洛文尼亚语 sl-sl 波兰语(波兰) pl-pl 瑞典语(瑞典) sv-se 西班牙语 (智利) es-cl

2.参考文档

  • https://ionicthemes.com/tutorials/about/internationalize-and-localize-your-ionic2-app-with-ngtranslate
  • http://www.gajotres.net/ionic-2-internationalize-and-localize-your-app-with-angular-2/
  • https://github.com/ngx-translate/core#installation
  • https://ionicframework.com/docs/v2/resources/ng2-translate/

semlinker avatar Mar 02 '17 11:03 semlinker