GetTextで日本語化してみる。

今まで、Ruby GetTextを利用するためには、以下のインストール作業が必要だと思っていた。

  • RubyGemsによるRuby GetTextのインストール
  • configureとmakeによるGNU GetTextのインストール

ところが、よくよく調べてみると、LocomotiveRailsを利用している環境では、Ruby GetText、GNU GetTextのどちらも、すでにインストールされていたのだ。今までのようにプラグインをインストールするまでもなく、日本語化*1する環境が整っていたとは...。早速、利用させて頂くことに。

      • どのように日本語化されるか確認するために、ActiveHeartやjascaffoldで日本語化する前のプロジェクトに戻して試してみた。

ファイルの基本設定

むとうさんのRuby on RailsでRuby-GetTextを使うを参考に、以下のように設定した。(感謝です!)

config/environment.rbへの追記
  • 最初と最後に以下の追記をした。
$KCODE = 'u'
require 'jcode'
...(途中省略)...
require 'gettext/rails'
app/controllers/application.rbへの追記と削除
  • オレンジ色の行を1行追加した。
  • コメント#にした行はすべて削除した。*2(#before_filter :set_charset〜#endまで。)
# Filters added to this controller will be run for all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
  init_gettext "softwarebook"

  #before_filter :set_charset
  
  #private
  #def set_charset
  #  headers['Content-Type'] = "text/html; charset=utf-8" unless request.xhr?
  #end
end

ここまで設定して、サーバーを再起動して確認してみる。

これだけで、すでにエラー表示は日本語化されている!(エラーの文言も、ちゃんと「。」で終わっているのが嬉しい。)

また、システム環境設定の言語環境で、最優先の言語を韓国語に変えてみると...

このように、韓国語で表示される。この時点で、エラー表示は多言語に対応しているようだ!素晴らしい!

lib/tasks/gettext.rakeファイルの新規作成

翻訳ファイルを抽出して、翻訳辞書に変換するrakeファイルを準備した。

  • RadRailsで、lib/tasksフォルダを右クリックして、新規 >> ファイルを選択、ファイル名をgettext.rakeにして追加した。
  • Ruby on RailsでRuby-GetTextを使うを参考に、以下のようにやってみた。オレンジ色の部分だけ変更した。
desc "Update pot/po files."
task :updatepo do
  require 'gettext/utils'
  GetText.update_pofiles(
    "softwarebook",  #テキストドメイン名(init_gettextで使用した名前) 
    Dir.glob("{app,config,components,lib}/**/*.{rb,rhtml}"),  #ターゲットとなるファイル
    "softwarebook 1.0.0")  #アプリケーションのバージョン
end

desc "Create mo-files"
task :makemo do
  require 'gettext/utils'
  GetText.create_mofiles(true, "po", "locale")
end

パスを通す!

Ruby GetTextをGNU GetTextと連携して使うためには、ターミナルからコマンドラインで操作すると上手く動いた。
Locomotiveにインストールされているソフトウェア群は、/Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/bin以下の深いディレクトリ階層にインストールされている。ターミナルから操作する利便性を考えれば、上記ディレクトリがコマンドサーチパスに登録されている方が使い勝手が良い。
ターミナルを起動して、PATH変数の内容を確認してみた。

MacBook:~ zari$ echo $PATH
/Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/bin:/usr/local/mysql/bin:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin

なんと、すでにパスは通っていた。(以前、別の問題で試行錯誤の中、設定したのだと思う。)
もし、設定されていない場合は、~/.bash_profileに追記する。picoで開いてみる。

MacBook:~ zari$ cd
MacBook:~ zari$ pico .bash_profile

自分のPATH変数の部分は以下のように設定されていた。(webブラウザの環境によっては、改行して表示されてしまうが、実際には1行で入力している)

export PATH=/Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/bin:/usr/local/mysql/bin:/usr/local/bin:/usr/local/sbin:$PATH

作業フロー

大まかな作業手順は、以下のような流れ。

  1. 翻訳が必要な文言を_()で囲む。例:_('Edit')
  2. .potファイルを作成する。(プロジェクトから翻訳対象の_(文言)を抽出したファイル)
  3. それを.poファイルに変換する。(.potファイルに翻訳文言を入力したファイル)
  4. さらに.moファイルに変換する。(実行時にGetTextが参照する翻訳辞書ファイル)

手作業は、3.で翻訳文言を入力する部分。それ以外はrakeコマンドが自動処理してくれる。

はじめての翻訳

そのプロジェクトで初めて翻訳する時までは「ちょっとだけ手間が掛かるかな...。」と思っていた。でも、正常に機能する手順が分かってしまえば、実はそんなに手間ではなかった。この後のメンテナンスの快適さや、多言語にも対応できることを考えると、日本語化の仕組みとして、ここで理解することが出来て良かった。
作業は以下の手順だ。(本当は事前に、ビューやモデルの翻訳対象の文言を_()で囲ってあげるべきだが、実験的に何も指定しないでやってみた。)

.potファイルの抽出
  • ターミナルを起動して、プロジェクトフォルダに移動する。
MacBook:~ zari$ cd ~/railsapp/softwarebook2
MacBook:~/railsapp/softwarebook2 zari$ rake updatepo
(in /Users/zari/railsapp/softwarebook2)
po/softwarebook.pot
  • RadRailsに戻って、softwarebook2プロジェクトを右クリックして「更新」すると...
    • po/softwarebook.potファイルとフォルダが作成されている。
    • 何も_()で囲まなくても、テーブル名とフィールド名は翻訳対象として抽出される。
.poファイルに変換
  • radRailsで、上記poフォルダを右クリックして、新規 >> フォルダを選択、フォルダ名jaで作成する。
  • ターミナルで、上記poフォルダにディレクトリを移動する。
MacBook:~/railsapp/softwarebook2 zari$ cd po
  • ターミナルで、msginitコマンドで.potファイルを.poファイルに変換する。
MacBook:~/railsapp/softwarebook2/po zari$ msginit -i softwarebook.pot -o ja/softwarebook.po
  • 以下のようなメッセージが出て、ユーザーが翻訳のフィードバックを送るメールアドレスを求められる。
The new message catalog should contain your email address, so that users can
give you feedback about the translations, and so that maintainers can contact
you in case of unexpected technical problems.

sed: 8: "{
h
s/^[^@]*@\(.*\)$/\1 ...": unterminated substitute pattern
Couldn't find out about your email address.
Please enter your email address.
taro@gmail.com
  • メールアドレスを入力すると...
sed: 8: "{
h
s/^[^@]*@\(.*\)$/\1 ...": unterminated substitute pattern
Retrieving http://www.iro.umontreal.ca/translation/registry.cgi?team=index... done.
Please visit your translation team's homepage at
  http://www.iro.umontreal.ca/translation/HTML/team-ja.html
  http://www.iro.umontreal.ca/contrib/po/HTML/teams.html
  http://www.iro.umontreal.ca/contrib/po/HTML/translators.html
  http://www.iro.umontreal.ca/contrib/po/HTML/index.html
and consider joining your translation team's mailing list
  

Created ja/softwarebook.po.
  • さらに処理は続き、ja/softwarebook.poファイルが作成された。
.poファイルを翻訳
  • poファイルの内容は、以下のようになっている。
# Japanese translations for softwarebook package.
# Copyright (C) 2006 THE softwarebook'S COPYRIGHT HOLDER
# This file is distributed under the same license as the softwarebook package.
# zarigani tosh <>, 2006.
#
msgid ""
msgstr ""
"Project-Id-Version: softwarebook 2\n"
"POT-Creation-Date: 2006-12-14 15:25+0900\n"
"PO-Revision-Date: 2006-12-14 15:37+0900\n"
"Last-Translator: zarigani tosh <>\n"
"Language-Team: Japanese \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"

#: app/models/keyword.rb:-
msgid "keyword"
msgstr ""

#: app/models/keyword.rb:-
msgid "Keyword|Name"
msgstr ""

#: app/models/software.rb:-
msgid "software"
msgstr ""

#: app/models/software.rb:-
msgid "Software|Title"
msgstr ""

#: app/models/software.rb:-
msgid "Software|Description"
msgstr ""

#: app/models/software.rb:-
msgid "Software|Url"
msgstr ""

#: app/models/software.rb:-
msgid "Software|Created on"
msgstr ""

#: app/models/software.rb:-
msgid "Software|Updated on"
msgstr ""

#: app/models/software.rb:-
msgid "Software|Keyword"
msgstr ""

#: app/models/software.rb:-
msgid "Software|User"
msgstr ""
  • msgidに対する翻訳文言msgstrを以下のように設定した。
...(途中省略)...
#: app/models/keyword.rb:-
msgid "keyword"
msgstr "キーワード"

#: app/models/keyword.rb:-
msgid "Keyword|Name"
msgstr "キーワード"

#: app/models/software.rb:-
msgid "software" ......テーブル名。エラー表示のタイトルなどに表示される。
msgstr "ソフトウェア"

#: app/models/software.rb:-
msgid "Software|Title" ......フィールド名。個々のエラーを警告するリストの項目名として表示される。
msgstr "タイトル"

#: app/models/software.rb:-
msgid "Software|Description"
msgstr "概要"

#: app/models/software.rb:-
msgid "Software|Url"
msgstr "URL"

#: app/models/software.rb:-
msgid "Software|Created on"
msgstr "作成日時"

#: app/models/software.rb:-
msgid "Software|Updated on"
msgstr "修正日時"

#: app/models/software.rb:-
msgid "Software|Keyword"
msgstr "キーワード"

#: app/models/software.rb:-
msgid "Software|User"
msgstr "" ......翻訳する必要が無ければ、入力しなくても良い。
.moファイルに変換
  • RadRailsの「Rakeタスク」タブで、プルダウンリストからmakemoを選択する。(なければ、直接キー入力する。)
  • /locale/ja/LC_MESSAGES/softwarebook.moファイルとフォルダが作成される。
  • ここまで、GetTextの作業で追加されたpoフォルダとlocaleフォルダの構成は以下のようになった。

  • 以上で、webブラウザで確認してみると、こんな感じで日本語化されている。エラー表示のテーブル名やフィールド名も、日本語で表示されるようになった。

2回目以降は、差分だけ翻訳

一度「はじめての翻訳」まで作業を進めてしまえば、その後のメンテナンス作業はとても快適だ。_('翻訳文言')のように囲ったら、翻訳したい時に、以下の手順を繰り返すだけ。

手順 作業環境 作業内容 作業結果
1 ターミナル rake updatepoコマンドを実行する。こうすればRadRailsで操作してもOK .potファイルと.poファイルが同時に差分更新される。
2 RadRails .poファイルを開いて対応する翻訳文言を差分だけ追記する。
3 RadRails 「rakeタスク」タブからmakemoコマンドを実行する。 .poファイルが.moファイルに変換される。
  • ターミナルでは上カーソルキーで、コマンド履歴を呼び出せるので、キー入力の手間は不要だ。
  • ターミナルで.potファイルや.poファイルが更新されると、RadRailsで再読み込みした時*3に「変更をロードしますか?」と確認してくる。必ず「はい」を選択する。

  • もし独自にRailsをインストールしていて、GNU GetTextがインストールされていないと、手順1のrake updatepoで、.poファイルが差分更新されない。それはとても不便なことなので、必ずGNU GetTextもインストールするべきだ。(Locomotive環境ならインストール済だ。)GNU GetText無しでは、このあと翻訳文言が増えてくると、やる気がなくなる...。
MacBook:~/railsapp/softwarebook2 zari$ rake updatepo MSGMERGE_PATH=rmsgmerge
      • RadRailsのRakeタスクからrake updatepoを実行すると、自分の環境では以下のようなエラーになってしまう...。おまけに.potファイルと.poファイルの内容もクリアされてしまう...。
      • 「msgmergeというコマンドが見つからない」と警告されていて、 その対象は/Applications/Locomotive2/.../ruby.rbファイルの96行目らしい。おそらく、RadRailsにmsgmergeコマンドのパスを教えてあげれば良いのだと思うのだが、その対処の仕方は不明...。残念。
(in /Users/zari/railsapp/softwarebook2)
po/softwarebook.pot
/Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/gettext-1.8.0/lib/gettext/parser/ruby.rb:96: command not found: msgmerge po/softwarebook.pot tmp.pot
po/ja/softwarebook.po
/Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/gettext-1.8.0/lib/gettext/parser/ruby.rb:96: command not found: msgmerge po/ja/softwarebook.po tmp.pot
      • 上記のエラーの解決策が見つかった。RadRailsの「Rakeタスク」タブでプルダウンメニューからupdatepoを選択して、右側の項目にMSGMERGE_PATH=/Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/bin/msgmergeと入力して実行すれば、RadRailsでも正常に機能した。さらに、解決策が見つかった!

*1:GetTextは日本語化だけに留まらず、様々な言語に対応することが出来る。つまり、国際化を実現するサポートをしてくれる。

*2:Ruby GetText内部で同等の処理をしてくれているので不要。

*3:RadRails以外で、ファイルやフォルダ構成を変更した場合は、対象のファイルをダブルクリックしたり、上位のフォルダで右クリックして「更新」を選択すると、その変更が反映される。