はじめに
i18n という gem は,Ruby on Rails アプリの多言語化のために使われているが,Rails 専用というわけではない。こいつを Rails とは無関係に単独で使うにはどうすればよいか。
えー,お急ぎの方は次の節へ飛んでください。
本家の README にはあまり情報が無い。リポジトリー にはサンプルファイルも見当たらない。
いっぱしのプログラマーならまずソースを読むところだが,いっぱしではないので安直なほうへ流れることにした(いやその前に定石として テスト を読もうとしたんだけど,どこを見ていいか分からず 20 秒で挫折)。
えー,「Ruby の I18n を単独で使う」でググります。
tbpgr さんのブログ記事「Ruby | i18nをRuby単独で利用する」が見つかる。
これに従ってやってみる。
ただ,この記事には不可解な点があった。i18n に翻訳ファイルを与えるところが
I18n.load_path = []
Dir.glob("../locale/*.yml").each do |f|
lang = []
lang << f
I18n.load_path << lang
end
になっているのだ。
lang
って変数は何をやっているのだろう? これって
I18n.load_path = Dir.glob("../locale/*.yml").map{|path| [path]}
でよいんでは? それとも転記ミスで,本当はもう少しややこしいコードだったのかな。
そもそも,I18n.load_path=
って,配列の配列を与える必要があるのか?
まあともかくやってみたら動いたので,とりあえずよし。
で,試した結果をもとに以下を書いていくことにする。
i18n は何をするもの
ウェブアプリケーションに限らず,アプリケーションを多言語化したい。
出てくる文言すべてにキーワードか何かを割り当てておき,言語ごとにキーワードと文言の対照表を編集しておくのだ。
アプリケーション上では,何か表示したいときにそのキーワードを指定する。どこかに言語のスイッチがあって,それによって実際に出てくる文言が変わる,と。
平たく言えばそういう仕組み。
i18n の使い方
インストール
まず i18n をインストール。
gem install i18n
翻訳ファイルの設置
翻訳ファイルを YAML 形式で用意。拡張子は .yaml
はダメで,.yml
にしなければならない。
拡張子でファイルの種類を見分けているようなので,たぶん YAML 形式以外のフォーマットにも対応してるんだと思う。
とりあえずちょっと試すだけなので,全言語を一つのファイルに収めることにする。規模が大きくなったら言語ごとに別のファイルにしたほうがいい。
ja:
orei: おおきに
ko:
orei: 감사합니다
ru:
orei: Спасибо
en:
orei: Thank you
これで準備完了。
使う
require 'i18n'
I18n.load_path = ["translation.yml"]
I18n.locale = :ja
puts I18n.t("orei") #=> おおきに
I18n.locale = :ko
puts I18n.t("orei") #=> 감사합니다
ちょー簡単。拍子抜けするくらいだ。
load_path は配列の配列にする必要はなかった(しても中で flatten
される)。
実際のアプリケーションでは言語ごとにファイルを分けるだろうから,それらのファイルへのパスの配列を渡せばいいだろう。
I18n.locale=
に渡すのは文字列でもシンボルでもいい。
翻訳データは入れ子にもできる。例えば ja のところを
ja:
foo:
bar: ばあ
と書いておけば,
I18n.locale = :ja
puts I18n.t("foo.bar") #=> ばあ
で呼び出せる。
おわりに
i18n にはきっといろんな機能があるんだろうし,知るべきこともいろいろあるんだろうけど,とりあえず当初の目的は果たせた。
おまけ(i18n)
「i18n」というのは,「internationalization」の略で,先頭の「i」と末尾の「n」の間に 18 字あることから,このような略し方にされているようだ。日常的に使う英単語の中では,20字はかなり長いほうだ。
似たような略語として「L10N」(localization)もある。
なんで「i18n」が小文字で「L10N」が大文字かというと,Wikipedia「国際化と地域化」 によれば,大文字の I(アイ)と小文字の l(エル)が互いに紛らわしいから避けたということらしい。
CIA(米国中央情報局)あたりでは counterintelligence(防諜活動)のことを「c17e」なんて略すんだろうか。