使用Angular-CLI发布一个i18n(国际化)应用(译)

使用Angular-CLI发布一个i18n(国际化)应用

原文作者:Philippe Martin
译者:王芃

原文地址:https://medium.com/@feloy/deploying-an-i18n-angular-app-with-angular-cli-fc788f17e358#.gkkec7fkt


在这篇文章中我将会解释如何使用angular-cli从头创建一个国际化的Angular2应用以及如何把这个应用部署到Apache服务器。

文中涉及到的软件依赖版本如下:

  • angular-cli:1.0.0-beta.24
  • angular: 2.4.1
  • Apache 2.4

文中描述的样例App已经放在github上了:https://github.com/feloy/angular-cli-i18n-sample

新鲜出炉的i18n App

我们首先使用angular-cli创建一个Angular App:

$ ng new angular-cli-i18n-sample

app.component.html 中,我们做一点小改动,加入一些用于i18n的文本:

<h1 i18n>Hello world!</h1>

接下来,我们需要创建一个 xlf 文件。但在创建之前,我们需要对 src/tsconfig.json 做一些小改动:

{
  "compilerOptions": {
    [...]
  },
  "exclude": [ "test.ts" ],
  "angularCompilerOptions": { "genDir": "i18n" }
}

package.json 中我们也需要加入一个脚本定义,使用 ng-xi18n 这个工具来生成一个可翻译的文本文件:

{
  [...]
  "scripts": {
    [...]
    "extract-i18n": "cd src && ng-xi18n"
  }
  [...]
}

现在,我们可以使用下面的命令来生成 src/i18n/messages.xlf 了:

$ npm run extract-i18n

我们现在要创建不同的语言翻译文件了,首先是英文翻译,拷贝 src/i18n/messages.xlfsrc/i18n/messages.en.xlf

[...]
      <trans-unit id="[...]" datatype="html">
        <source>Hello World!</source>
        <target>Hello World!</target>
      </trans-unit>
[...]

同样创建法语的 src/i18n/messages.fr.xlf :

[...]
      <trans-unit id="[...]" datatype="html">
        <source>Hello World!</source>
        <target>Salut la foule !</target>
      </trans-unit>
[...]

再来创建一个西班牙版本 src/i18n/messages.es.xlf

[...]
      <trans-unit id="[...]" datatype="html">
        <source>Hello World!</source>
        <target>¿hola, qué tal?</target>
      </trans-unit>
[...]

现在我们可以使用 angular-cli 在启动应用时使用你的语言偏好,以西班牙语为例:

$ ng serve --aot \
           --i18n-file=src/i18n/messages.es.xlf \
           --locale=es \
           --i18n-format=xlf

现在你可以打开浏览器访问 http://localhost:4200 ,然后就应该可以看到西班牙语版本的应用了。

发布到生产环境的准备工作

在生产环境,我们希望依照不同语言,以不同的子目录的形式呈现不同语言版本的app。例如西班牙语版本可以通过 http://myapp.com/es/ 来访问;而法语版本通过 http://myapp.com/fr/ 来访问。当然我们还希望根URL http://myapp.com/ 可以重定向到我们选择的语言选项。

要这么做的话,我猜我们需要根据不同的语言来改变 base href,比如改成 es, enfr。幸运的是,angular-cli 有一个特殊的命令行开关:--bh,这个开关允许我们在编译时声明 base href

下面给出一个命令行脚本(译者注:*nix版本可用,windows版本需要改写一下),这个脚本可以帮我们为不同语言创建不同的bundle

$ for lang in es en fr; do \
    ng build -o dist/$lang \
             --aot \
             -prod \
             --bh /$lang/ \
             --i18n-file=src/i18n/messages.$lang.xlf \
             --i18n-format=xlf \
             --locale=$lang; \
  done

当然我们可以在 package.json 中给出这个命令的脚本定义,这样我们就可以使用npm脚本来执行了:npm run build-i18n

{
  [...]
  "scripts": {
    [...]
    "build-i18n": "for lang in en es fr; do ng build -o dist/$lang --aot -prod --bh /$lang/ --i18n-file=src/i18n/messages.$lang.xlf --i18n-format=xlf --locale=$lang; done"
  }
  [...]
}

现在,我们在dist目录下有了3个子目录: es/fr/en/ ,里面有对应不同语言的bundle。

Apache配置

下面是一个虚拟主机配置,这个配置在 /var/www 目录来启动我们的不同版本的bundle文件,所以我们得把刚刚生成的3个目录 es/fr/en/拷贝到这里。

有这样一个配置后,访问 http://www.myapp.com 会根据浏览器优选的语言首选项来重定向到不同的子目录(如果没有匹配的语言时 en作为fallback)。当然你可以通过改动url来访问其他语言版本。

<VirtualHost *:80>
  ServerName www.myapp.com
  DocumentRoot /var/www
  <Directory "/var/www">
    RewriteEngine on
    RewriteBase /
    RewriteRule ^../index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (..) $1/index.html [L]
    RewriteCond %{HTTP:Accept-Language} ^fr [NC]
    RewriteRule ^$ /fr/ [R]
    RewriteCond %{HTTP:Accept-Language} ^es [NC]
    RewriteRule ^$ /es/ [R]
    RewriteCond %{HTTP:Accept-Language} !^es [NC]
    RewriteCond %{HTTP:Accept-Language} !^fr [NC]
    RewriteRule ^$ /en/ [R]
  </Directory>
</VirtualHost>

加餐:为不同语言增加链接

如果在应用中有不同语言的选项链接,用户可以点击这些链接来访问不同语言版本,那就太好了(译者注:汗,这不是标配需求吗?)。

在Angular2中,需要知道一个小技巧:当前语言是可以通过 LOCALE_ID 取得的。

下面我们演示一下如何取得 LOCALE_ID、显示不同语言的列表:

// app.component.ts
import { Component, LOCALE_ID, Inject } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  languages = [
    { code: 'en', label: 'English'},
    { code: 'es', label: 'Español'},
    { code: 'fr', label: 'Français'}
  ];
  constructor(@Inject(LOCALE_ID) protected localeId) {}
}
<!-- app.component.html -->
<h1 i18n>Hello World!</h1>
<template ngFor let-lang [ngForOf]="languages">
  <span *ngIf="lang.code !== localeId">
    <a href="/{{lang.code}}/">{{lang.label}}</a> </span>
  <span *ngIf="lang.code === localeId">{{lang.label}} </span>
</template>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容

  • 中文翻译 ng help ng build 构建您的应用程序并将其放入输出路径(dist /默认情况下)。 别名:...
    4ea0af17fd67阅读 1,932评论 0 0
  • 导语 Angular2(已经统一更名为Angular,而Angular1表示1.x版本,以下统称Angular都是...
    cipchk阅读 2,733评论 1 46
  • Angular CLI 是什么? Angular CLI 是一个命令行接口(Command Line Interf...
    semlinker阅读 4,132评论 0 39
  • 如果您是来找前端国际化解决方案的 那么我推荐一篇https://github.com/OneWayTech/i1...
    江火渔枫阅读 14,760评论 0 5
  • 第一次听这首歌是在电视剧里,它是插曲。可是就是这样一首简单的歌曲却让我单曲循环了一年。听着它的时候,时间过得特别快...
    程曦light阅读 308评论 0 0