Angular2 > Angularで国際化対応 †国際化の方法 †やり方はいくつかあって、大きく以下の2つに分けられる
2つの方法を比較した所感 †ngx-translate の方が全然使いやすい。 Angular標準 †Angular標準の方は、翻訳対象箇所が増える度に、翻訳用のファイルを生成し直す必要がある為、メンテナンス性は良くない。 ngx-translate †単純な翻訳ならテンプレートの記述がシンプル。(タグに "translate" 属性を付けるだけ) 準備 †ng new my-app && cd my-app ng generate component header ng generate component top ng generate component page1 ng generate component page2 src/app/app.module.ts . + import { RouterModule } from '@angular/router'; . . @NgModule({ declarations: [ AppComponent, HeaderComponent, TopComponent, Page1Component, Page2Component ], imports: [ BrowserModule, + RouterModule.forRoot([ + { path: 'top', component: TopComponent }, + { path: 'page1', component: Page1Component }, + { path: 'page2', component: Page2Component } + ], { useHash: true }) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } src/app/app.component.html <!-- headerコンポーネント --> <app-header></app-header> <!-- ルーターがコンポーネントを表示する場所 --> <div id="content"> <router-outlet></router-outlet> </div> src/app/header/header.component.html <a routerLink="/top" routerLinkActive="active">Top</a> <a routerLink="/page1" routerLinkActive="active">page1</a> <a routerLink="/page2" routerLinkActive="active">page2</a> Angular標準の国際化対応を利用する場合 †Internationalization (i18n) として、公式ドキュメント(※)に記載されている。 テンプレートの翻訳対象箇所を修正する †翻訳対象のタグに i18n="@@xxx" を追加する src/app/header/header.component.html <a routerLink="/top" routerLinkActive="active" i18n="@@top">Top</a> <a routerLink="/page1" routerLinkActive="active" i18n="@@page1">page1</a> <a routerLink="/page2" routerLinkActive="active" i18n="@@page2">page2</a> 翻訳ソースファイルを生成する †ng xi18n --outputPath src/locale ls -1 src/locale/ messages.xlf 翻訳ソースファイルをコピーして日本語用のファイルを作成 †cp src/locale/messages.xlf src/locale/messages.ja.xlf 翻訳内容を記載する †src/locale/messages.ja.xlf <?xml version="1.0" encoding="UTF-8" ?> <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 id="top" datatype="html"> <source>Top</source> + <target>トップ</target> <context-group purpose="location"> <context context-type="sourcefile">app/header/header.component.ts</context> <context context-type="linenumber">1</context> </context-group> </trans-unit> <trans-unit id="page1" datatype="html"> <source>page1</source> + <target>ページ1</target> <context-group purpose="location"> <context context-type="sourcefile">app/header/header.component.ts</context> <context context-type="linenumber">2</context> </context-group> </trans-unit> <trans-unit id="page2" datatype="html"> <source>page2</source> + <target>ページ2</target> <context-group purpose="location"> <context context-type="sourcefile">app/header/header.component.ts</context> <context context-type="linenumber">3</context> </context-group> </trans-unit> </body> </file> </xliff> ローカルサーバ起動 †ng serve --aot --i18nFile=src/locale/messages.ja.xlf --i18nFormat=xlf --locale=ja ビルド †ng build --aot --i18nFile=src/locale/messages.ja.xlf --i18nFormat=xlf --locale=ja --output-path=/path_to_www/angular2-ja --bh /angular2-ja/ 動的に切り替える場合 †動的に言語を切り替える方法で見つかったのは、それぞれの言語用にビルドして別のディレクトリに配意するやり方だけだった。 ng build --aot --i18nFile=src/locale/messages.en.xlf --i18nFormat=xlf --locale=en --output-path=/path_to_www/angular2-en --bh /angular2-en/ ng build --aot --i18nFile=src/locale/messages.ja.xlf --i18nFormat=xlf --locale=ja --output-path=/path_to_www/angular2-ja --bh /angular2-ja/ ng build --aot --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr --output-path=/path_to_www/angular2-fr --bh /angular2-ja/ ngx-translateを利用する場合 †https://github.com/ngx-translate/core インストール †npm install @ngx-translate/core --save npm install @ngx-translate/http-loader --save ローダーを使用して翻訳できるようにソース変更 †src/app/app.module.ts . . + import {HttpClientModule, HttpClient} from '@angular/common/http'; + import {TranslateModule, TranslateLoader} from '@ngx-translate/core'; + import {TranslateHttpLoader} from '@ngx-translate/http-loader'; . . + export function createTranslateLoader(http: HttpClient) { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); + } @NgModule({ . . imports: [ . . + HttpClientModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [HttpClient] + } + }), . . src/environments/environment.ts export const environment = { production: false, + defaultLang: 'en' }; src/app/app.component.ts +import {TranslateService} from '@ngx-translate/core'; +import { environment } from '../environments/environment'; export class AppComponent { title = 'app'; + constructor(private translate: TranslateService) { + translate.setDefaultLang(environment.defaultLang); + translate.use(environment.defaultLang); + } } 辞書ファイルの作成 †mkdir -p src/assets/i18n src/assets/i18n/en.json { "top":"top", "page1":"page1", "page2":"page2" } src/assets/i18n/ja.json { "top":"トップ", "page1":"ページ1", "page2":"ページ2" } HTMLテンプレートを修正 †タグの内容をそのまま翻訳する場合は translate 属性をつけるだけでOK。 src/app/header/header.component.html <a routerLink="/top" routerLinkActive="active" translate>top</a> <a routerLink="/page1" routerLinkActive="active" translate>page1</a> <a routerLink="/page2" routerLinkActive="active" translate>page2</a> ※その他のケースは https://github.com/ngx-translate/core を参照。 サーバ起動 †普通にサーバを起動するだけ ng serve 動的に切り替える場合 †TranslateService.use で普通に切り替えられる src/environments/environment.ts export const environment = { production: false, defaultLang: 'en', + languages: [ {'lang': 'en', 'label': 'English'}, {'lang': 'ja', 'label': 'Japanese'} ] }; src/app/header/header.component.html[ <select (change)="changeLang($event.target.value)"> <option *ngFor="let lang of languages; let i = index;" [value]="lang.lang" [selected]="isCurrentLang(lang.lang)"> <span translate>{{lang.label}}</span> </option> </select> src/assets/i18n/en.json { "English": "English", "Japanese": "Japanese", "top":"Top", "page1":"Page1", "page2":"Page2" } src/assets/i18n/ja.json { "English": "英語", "Japanese": "日本語", "top":"トップ", "page1":"ページ1", "page2":"ページ2" } src/app/header/header.component.ts import {TranslateService} from '@ngx-translate/core'; import { environment } from '../../environments/environment'; export class HeaderComponent implements OnInit { . . + languages = environment.languages; + currentLang: string = environment.defaultLang; + constructor(private translate: TranslateService) {} + + changeLang(lang){ + if (lang !== this.currentLang) { + this.translate.use(lang); + this.currentLang = lang; + } + } + + isCurrentLang(lang){ + return lang === this.currentLang; + } |