ふるてつのぶろぐ

福岡在住のエンジニアです。

写真提供:福岡市

Angular7 + Bootstrap4 で Web アプリを作ろう - ngx-translate で他言語化の件 。

こんにちはふるてつです。
今日は土曜日、ちょっとくもり。わたしは家でAngularを自習しています。
今回のテーマは他言語です。
勤務先で ngx-translate を使って他言語化した方がいて、話を聞いていると思ったより簡単そうだと感じました。
Angular純正もあったかと思いましたが、ネットでも ngx-translate がよさそうとの評もあり今回試してみました。 https://qiita.com/daikiojm/items/def764b12c8ff2ebbc92

ngx-translate のインストール

まず下記の CLI コマンドでインストールします。
https://github.com/ngx-translate/core (Gitリポジトリ)を参考にして設定します。

ngx-translate の core と http-loader が必要そうです。
両方ともにインストールします。

npm install @ngx-translate/core --save
npm install @ngx-translate/http-loader --save

なぜ@を ngx-translate/core の前につけるかというと「node_modules」フォルダの中に@付きでライブラリを入れるためです。
言い換えると他のライブラリと区別しやすくするためです。

インストール完了後のターミナル
f:id:tetsufuru:20190323110024p:plain もうひとつ。サクッとうまくいきました。
f:id:tetsufuru:20190323112323p:plain

package.json には ngx-translate/core が追加されました。
f:id:tetsufuru:20190323113917p:plain

package-lock.json も変わりました。 f:id:tetsufuru:20190323113952p:plain

AppModule クラスの修正

まずAppモジュールの中に TranslateModule の import を追加します。
このあたりの設定は Git リポジトリの README.MD の 中段あたり Configuration のところに書いてあります。
TranslateHttpLoaderというクラスを使用して、HTTPで 他言語用の json ファイルを読み込んで変換します。
json ファイルは "/assets/i18n/[lang].json" に置く感じになります。

TranslateModule.forRoot({
    loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
    }
})

あと TranslateHttpLoader を返すメソッドを一つ追加しました。 これも手順通りです。

export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

AppModule クラスのコード全体は下記になりました。

// 機能に関するモジュール類
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { FormsModule } from '@angular/forms';
import { environment } from '../environments/environment';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

// コンポーネント関連
import { AppComponent } from './app.component';
import { HeaderComponent } from './component/common/header/header.component';
import { FooterComponent } from './component/common/footer/footer.component';

import { SignInComponent } from './component/pages/sign-in/sign-in.component';
import { EvaluationResultComponent } from './component/pages/evaluation-result/evaluation-result.component';
import { SearchInfoComponent } from './component/common/search-info/search-info.component';
import { MessagesComponent } from './component/common/message/messages/messages.component';
import { ErrorMessagesComponent } from './component/common/message/error-messages/error-messages.component';

// 他言語化の設定
export function HttpLoaderFactory(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

// モジュール定義
@NgModule({
  declarations: [
    AppComponent,
    HeaderComponent,
    FooterComponent,
    SignInComponent,
    EvaluationResultComponent,
    SearchInfoComponent,
    MessagesComponent,
    ErrorMessagesComponent
  ],
  imports: [
    BrowserModule, NgbModule.forRoot(),
    FormsModule, AppRoutingModule, HttpClientModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: HttpLoaderFactory,
        deps: [HttpClient]
      }
    })
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

上のコードが長くなり見にくくスミマセン。

AppModule クラスの修正

次は一旦 AppComponent のコンストラクタで TranslateService をインジェクトして、日本語を使用するよう設定しておきます。
今後どのようにするかまだ決めていませんが、ブラウザの言語設定に合わせて切り替えるか? DBにユーザ毎の言語設定を登録して切り替えるか?どちらかにすると思います。

AppComponent クラスのコードは下記になります。
コンストラクタで TranslateService をインジェクトしてデフォルトの言語と使用する言語を設定しました。

import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'sanrokumaru';

  constructor(translate: TranslateService) {
    // 言語の初期設定
    translate.setDefaultLang('en');
    translate.use('ja');
  }

}

json ファイルの作成

assets/i18n/に en.json と ja.json 2ファイルを作ります。
f:id:tetsufuru:20190323225040p:plain

json の中身は下記です。
フォーマットを間違えなければ、どういうまとめ方でも構わないと思います。

{
  "welcomeScreen": {
    "title": "ようこそ",
    "systemName": "Sanrokumaruシステムへ",
    "comment": "より良いコミュニケーションを目指して"
  },
  "signInScreen": {
    "signIn": "サインイン",
    "userId": "ユーザID",
    "password": "パスワード",
    "signInBtn": "サインイン",
    "information": "お知らせ"
  }
}

html の書き換え

あとは html の中で直に文言を書き込んでいる個所を書き換えるだけです。

まずは簡単な書き方です。下記のような label の例になります。
タグの中に translate を追記し文言を json のキーに置き換えます。

<label for="loginUserId">ユーザID</label>
↓ 変更後
<label for="loginUserId" translate>signInScreen.userId</label>

次はちょっと難しい分。例はプレースホルダーになります。 {{}}の中に json のキーを追記し、パイプで translate をするように書きます。

<input id="loginUserId" type="text" placeholder="ユーザID">
↓ 変更後
<input id="loginUserId" type="text" placeholder="{{ 'signInScreen.userId' | translate }}">

あとは大体似たような感じで、サインイン画面の文言を他言語化しました。

日本語の時は下記 f:id:tetsufuru:20190323231129p:plain

英語の時は下記のようになります。 f:id:tetsufuru:20190323231024p:plain

今日の感想

今日は ngx-translate を使って他言語化にチャレンジしました。
1画面だけですが思ったより簡単にできました。
コードを書くよりこのブログを書く方に時間がかかったくらいです。
今後の他言語化は全部これで行こうか~と思いました。

では、今日もお疲れ様でした。