由緒正し I18n の仕組みということを、 Phoenix を触るようになって初めて知りました。
Phoenix ではプロジェクトを作成すると自動的にパッケージが追加されますが、通常の Elixir プロジェクトで利用する手順を調べました。
くわしくは公式ドキュメントに全部書いてあります。
プロジェクトを用意する
$ mix new my_app
$ cd my_app
パッケージを追加する
バージョンはそのときどきの適切な(たいていは最新の)バージョンを指定してください。
defp deps do
[
{:gettext, "~> 0.15.0"}
]
end
$ mix do deps.get, deps.compile
実行すると gettext 関連のタスクが追加されます。
$ mix help
...
mix gettext.extract # Extracts translations from source code
mix gettext.merge # Merge template files into translation files
...
プロジェクトの Gettext モジュールを作る
こんな感じで。
defmodule MyApp.Gettext do
use Gettext, opt_app: :my_app
end
Gettext を利用したコードを書く
たとえばこんな感じで。
defmodule MyApp do
import MyApp.Gettext
def say do
IO.puts gettext("Hello, %{name}!", name: "世界")
IO.puts gettext("Hi.")
IO.puts gettext("Bye.")
end
end
実行するとこんな感じ。まだなにもしていないので gettext
に与えられた文字列がそのまま出力されています。
$ mix run -e 'MyApp.say'
Hello, 世界!
Hi.
Bye.
文字列を抽出する
mix gettext.extract
を実行して文字列を抽出します。
priv/gettext/default.pot
というファイルが作成され、抽出した文字列が格納されます。
$ mix gettext.extract
Compiling 2 files (.ex)
Extracted priv/gettext/default.pot
ロケールに対応した .po ファイルを作成する
$ mix gettext.merge priv/gettext --locale=ja
Created directory priv/gettext/ja/LC_MESSAGES
Wrote priv/gettext/ja/LC_MESSAGES/default.po
priv/gettext
の下に指定したロケールのディレクトリが作成され、その中に default.po
というファイルが作成されます。
msgid
が gettext
に与えた文字列で、文字列を置き換える時の ID になります。
msgstr
に置き換える文字列を記述します。このときプレイスホルダ(ここでは %{name}
の部分)は置き換え後も機能するようにそのまま残します。
たとえばこんな感じ。
msgid ""
msgstr ""
"Language: ja\n"
"Plural-Forms: nplurals=1\n"
#, elixir-format
#: lib/my_app.ex:7
msgid "Bye."
msgstr "ぢゃ、そんな感じで。"
#, elixir-format
#: lib/my_app.ex:5
msgid "Hello, %{name}!"
msgstr "こんにちは、%{name}!"
#, elixir-format
#: lib/my_app.ex:6
msgid "Hi."
msgstr "やはぁ。"
デフォルトのロケールを指定する
config/config.exs
にデフォルトロケールの指定を追加します。
config :my_app, MyApp.Gettext,
default_locale: "ja"
$ mix compile --force
Compiling 2 files (.ex)
Generated my_app app
$ mix run -e 'MyApp.say'
こんにちは、世界!
やはぁ。
ぢゃ、そんな感じで。
文字列を追加する
Gettext を使う文字列を追加してみます。
defmodule MyApp do
import MyApp.Gettext
def say do
IO.puts gettext("Hello, %{name}!", name: "世界")
IO.puts gettext("Hi.")
IO.puts gettext("Leave it to me!")
IO.puts gettext("Bye.")
end
end
抽出します。
$ mix gettext.extract
Compiling 2 files (.ex)
Extracted priv/gettext/default.pot
priv/gettext/default.pot
に追加した文字列が追加されます。
ロケールの .po
ファイルにマージします。
$ mix gettext.merge priv/gettext --locale=ja
Wrote priv/gettext/ja/LC_MESSAGES/default.po
priv/gettext/ja/LC_MESSAGES/default.po
を編集します。
#, elixir-format
#: lib/my_app.ex:7
msgid "Leave it to me!"
msgstr "むぁ〜かせて!"
再コンパイルして実行します。
$ mix compile --force
Compiling 2 files (.ex)
Generated my_app app
$ run -e 'MyApp.say'e
こんにちは、世界!
やはぁ。
むぁ〜かせて!
ぢゃ、そんな感じで。
Gettext.put_locale/1
にロケールの文字列を指定すると動的にロケールを変更できます。
$ mix run -e 'Gettext.put_locale("en"); MyApp.say'
Hello, 世界!
Hi.
Leave it to me!
Bye.
もしくは。
MyApp.Gettext
のロケールのみを変更したいばあいは、Gettext.put_locale/2
を使ってモジュールを指定します。
$ mix run -e 'Gettext.put_locale(MyApp.Gettext, "en"); MyApp.say'
Hello, 世界!
Hi.
Leave it to me!
Bye.
$ mix run -e 'Gettext.put_locale(MyApp.Gettext, "en"); MyApp.say; Gettext.put_locale(MyApp.Gettext, "ja"); MyApp.say'
Hello, 世界!
Hi.
Leave it to me!
Bye.
こんにちは、世界!
やはぁ。
むぁ〜かせて!
ぢゃ、そんな感じで。
Phoenix プロジェクトを作成すると、パッケージが追加された状態で priv/gettext
も用意された状態になっています。
$ mix phx.new my_phx
my_phx/
└── priv/
└── gettext/
├── en/
│ └── LC_MESSAGES/
│ └── errors.po
└── errors.pot
ここで mix gettext.extract
を実行すると、lib/my_phx_web/templates/page/index.html.eex
の "Welcome to %{name}!"
が priv/gettext/default.pot
に抽出されます。
$ mix gettext.extract
Compiling 12 files (.ex)
Generated my_phx app
Extracted priv/gettext/errors.pot
Extracted priv/gettext/default.pot
同様に mix gettext.merge
を実行します。
$ mix gettext.merge priv/gettext --locale=ja
Created directory priv/gettext/ja/LC_MESSAGES
Wrote priv/gettext/ja/LC_MESSAGES/errors.po
Wrote priv/gettext/ja/LC_MESSAGES/default.po
生成された priv/gettext/ja/LC_MESSAGES/default.po
を編集します。
#, elixir-format
#: lib/my_phx_web/templates/page/index.html.eex:2
msgid "Welcome to %{name}!"
msgstr "%{name}へようこそ!"
config/config.exs
を編集してデフォルトロケールの指定を追加します。
config :my_phx, MyPhxWeb.Gettext,
default_locale: "ja"
サーバを起動します。
$ mix phx.server
ブラウザで http://localhost:4000
にアクセスします。
ぢゃ、そんな感じで。
いつか読むはずっと読まない:なぜなら、猫だから
本書の帯より。
この本に登場する猫たち
- マシュマロを焼く天才猫
- マスコットとして宇宙船に乗った猫
- 銀河文明を変えた猫
- 生き返ってから年を取らなくなった猫
- テレパスになった猫