karlley's tech blog

学習メモや記録とか

i18nで多言語化する設定

前回の記事i18nの概要は掴んだつもりなので、実際に多言語化する設定を行います。 多言語化する方法はいくつかありますが、一番シンプルそうなparamsで言語を切り替える方法を行います。

結論

下記手順で多言語化の設定を行う。

  1. デフォルト言語設定、ロケールファイルの読込設定
  2. URLクエリパラメータでロケールの切替設定
  3. ロケールファイルの作成

学習用アプリのリポジトリ: karlley/fjord-books_app at 02-i18n

1. デフォルト言語設定、ロケールファイルの読込設定

  • デフォルトロケールの設定をconfig/application.rb に記述する。
  • config/locals 以下にディレクトリを追加したい場合はロケールファイルへのファイルパス(I18n.load_path)を追加する。

訳文読み込みパス (I18n.load_path) はファイルへのパスの配列であり、自動的に読み込まれます。このパスを設定することで、訳文のディレクトリ構造やファイル命名スキームをカスタマイズできます。

I18のバックエンドは、訳文が初めて参照されるときに遅延読み込みを行います。これにより、訳文を既に公開した後でもバックエンドを他のものに差し替えることができます。

設定のポイント

  • i18nのデフォルトロケール:en に設定されている。
  • config/locales ディレクトリ直下の.rbファイルと.ymlファイルは、自動的に訳文読み込みパス(I18n.load_paths)に追加される。
  • I18n.load_pathsに直接追加すると、外部gemが翻訳されない。

1-1. デフォルト言語設定

config/application.rb にデフォルト言語設定を追記。

# config/application.rb

require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module BooksApp
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.1

    # デフォルト言語指定
    config.i18n.default_locale = :ja # 追記

    # Configuration for the application, engines, and railties goes here.
    #
    # These settings can be overridden in specific environments using the files
    # in config/environments, which are processed later.
    #
    # config.time_zone = "Central Time (US & Canada)"
    # config.eager_load_paths << Rails.root.join("extras")
  end
end

1-2. ロケールファイルの読込設定

下記のようなconfig/locales ディレクトリ内でロケールファイルを分割する場合のみに必要な設定です。 I18n.load_path に直接ファイルパスを指定します。

config
└── locales
       ├── model
       │     ├── ja.yml
       │     └── en.yml
       ├── controller 
       │     ├── ja.yml
       │     └── en.yml
       └── view 
              ├── ja.yml
              └── en.yml

[初学者]Railsのi18nによる日本語化対応 - Qiita

  • I18n.load_pathに直接パスを追加すると、外部gemが翻訳されないことに注意すること。
  • デフォルト言語設定より前にファイルパスの設定を記述する。
# config/application.rb

...

module BooksApp
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.1

    # 多言語化
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
    # ファイルパスを追加
    config.i18n.default_locale = :ja

  ...

  end
end

rails c で設定したファイルパスへ渡す値の中身を確認してみます。

  • Rails.root でアプリケーションのルートパスを取得。
  • Rails.root.join('config', 'locales', '**', '*.{rb,yml}') でルートパス以下のconfig/locals 配下の*.rb or *.yml ファイルへのパスを取得。
  • Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]config/locales 配下の各ロケールファイルのファイルパスを文字列に変換し、配列として取得。この際、追加したロケールファイル毎のファイルパスが配列としてconfig.i18n.load_path に渡される。
$ rails c
> Rails.root
=> #<Pathname:/Users/karlley/Workspace/fjord-books_app>

> Rails.root.join('config', 'locales', '**', '*.{rb,yml}')
=> #<Pathname:/Users/karlley/Workspace/fjord-books_app/config/locales/**/*.{rb,yml}>

# config/locals/test/ja.yml を追加した場合のファイルパス
> Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
=> ["/Users/karlley/Workspace/fjord-books_app/config/locales/en.yml",
    "/Users/karlley/Workspace/fjord-books_app/config/locales/ja.yml",
    "/Users/karlley/Workspace/fjord-books_app/config/locales/test/ja.yml"]

2. URLクエリパラメータでロケールの切替設定

前回の記事の中のparamsでのロケール切替を行います。

  • I18n.locale=I18n.with_localeを使わない場合はデフォルトのロケールが使われる。
  • I18n.with_locale を使うことでI18n.locale の設定漏れを防げる。
  • application_controller.rb に設定を追記することで全controllerでロケール設定が適応される。

app/controllers/application_controller.rbaround_actionロケール切替の処理を追加します。

# app/controllers/application_contorller.rb

# frozen_string_literal: true

class ApplicationController < ActionController::Base
  before_action :switch_locale

  def switch_locale(&action)
    locale = params[:locale] || I18n.default_locale
    I18n.with_locale(locale, &action)
  end
end

Railsアプリを多言語化に対応して国際的アプリにする 【設定編】 - Qiita

3. ロケールファイルの作成

翻訳の為のロケールファイルを作成します。ロケールファイルのファイル形式はyamlです。

yamlについて

インデントで階層を表現する人間にとって読みやすい構造化されたデータを表現するフォーマット。

  • コメントは#で記述可能
  • タブは使用不可
  • インデントは一般的に半角スペース2つ(階層毎に左揃えになっていればスペースの数は2つ以外でもokらしい)

プログラマーのための YAML 入門 (初級編)

3-1. ロケールファイルの作成

日本語、英語用のロケールファイルを作成します。 今回は下記のようにconfig/locales ディレクトリ直下にja.ymlen.yml の2つのロケールファイルを作成します。 en.yml はデフォルトで作成されているのでja.yml のみ新規作成します。

config
└ locales
   ├ ja.yml
   └ en.yml

3-2. 翻訳の反映を確認

作成したロケールファイルに下記の翻訳情報を追加し、翻訳されるか確認します。

# config/locales/en.yml

en:
  hello: "Hello"
# config/locales/ja.yml

ja:
  hello: "こんにちは"

今回はURLクエリパラメータでロケールを切り替えるので実際にパラメータを渡して翻訳されるのか確認します。

  1. 動作確認用にapp/views/books/index.html.erb に追記。
  2. rails s でサーバを起動。
  3. http://localhost:3000/books にアクセス時にデフォルト言語で翻訳されるか確認(今回の場合はこんにちは)。
  4. http://localhost:3000/books?locale=en にアクセス時に英語で翻訳されるか確認(Hello と表示される)。
# 動作確認用の追記内容
# app/views/books/index.html.erb

<%= t :hello %>

動作が確認できたらapp/views/books/index.html.erb の追記した内容は削除してください。

まとめ

設定の内容自体は全く難しいことはしていないのですが、設定に関する情報が多いので必要な情報を探すのが大変でした。 設定が間違っている可能性もあるので随時修正していきたいと思います。

参照

Rails 国際化(i18n)API - Railsガイド

[初学者]Railsのi18nによる日本語化対応 - Qiita

Railsアプリを多言語化に対応して国際的アプリにする 【設定編】 - Qiita

プログラマーのための YAML 入門 (初級編)