ひさびさに新規案件担当することになりまして。言語は残念ながら PHP が指定されているんですが(個人的には Perl/Ruby/Python あたりのほうが好き)フレームワークは自由に選んでいいという話。
今回は管理系の画面で CRUD 処理がメインだから CakePHP とか symfony とかそれ系のフレームワークがいいかなー?と思って機能を調べてると、CakePHP 1.2 で多言語対応が強化されてるっぽい。今回は英語サイトと日本語サイトが必要なので、これはなかなかいいんじゃない?
ということで、CakePHP の多言語対応について調べたことメモ。
■基本的なところ
CakePHP のおいしい食べ方: CakePHP1.2の簡単国際化
CakePHPで国際化の方法を試してみました : アシアルブログ
このあたり、ひととおり内容がまとまってる。後者は cake_1.2.0.6311-beta で .mo の読み込みがうまくいかない件についても書かれてるけど、現段階では .po で十分だから 1.2 の正式リリース待ちでいいかな。
■ところで .po とかってどういう意味?
なんの略語かわからないと覚えにくいので調べてみた。
翻訳ファイルを用意してプラグインを日本語化する | WordPressで企業ウェブサイト作成・商用ホームページ制作 WordPress Go Go
によると、.po、.pot、.mo ってのは
gettext 由来で、こういう意味だそうな。
POT (Portable Object Template)
ソースコードの中から先ほどの__()と_e()のメッセージをすべて抽出した翻訳リソースのもとになるファイルだ。実質的には.poファイルと同じだと思うが、元の翻訳リソースファイルとして.potファイルといわれる。ちなみに.potはPowerPointのテンプレートファイルと同じ拡張子である。
PO (Portable Object)
上の.potファイルをもとに各言語に翻訳したものが.poファイルである。
MO (Machine Object)
その名の通り、.poファイルを機械が効率よく読み込めるようにしたバイナリファイルが.moファイルである。
__(〜)
って表記も WordPress と同様だけど、遡るとやっぱり gettext の
_(〜)
が元っぽい。
(2009-04-06 追記)
PHP 標準でも gettext の機能が使えたんですね・・・。Referer 経由で知りました。
floatingdays: CakePHP 1.2 で多国語対応(GetText)調査メモ
> PHPでは _() または gettext() でgettextできるが、CakePHPではそれをラップして __() でgettextできる。
■Poedit について
上の WordPress の説明からさらにリンクを辿ると、詳しい使い方が書いてある。
poEdit で翻訳ファイルを作る ≪ iDeasilo
ショートカットについて書かれてないのでそこだけ補足すると、
・Ctrl+Enter でビューを切り替え
・Alt+C で原文コピー
みたいな感じ。基本的に前者でがしがし書いて、%s が複数入るような長文なんかは原文コピーするのが楽かな。
■CakePHP 用の .po ファイルってないの?
結構決まりきった翻訳が多いと思うんだけど、標準セットみたいなのないのかな?と思って探してみると、やっぱりあるっぽい。というか色々参考になった。
1.2系の多言語対応メモ(1) - Writing Some Code
→ja と jpn の対応とかについて。
1.2系の多言語対応メモ(2) - Writing Some Code
→LC_MESSAGES 以外について。あと複数形の記述ルールについて。
1.2系の多言語対応メモ(3) - Writing Some Code
→コア部分の翻訳ファイルについて。あと複数 %s がある場合の注意点。
ということで、最後のところに書いてるとおり core.po ってのを準備すれば OK なんだけど、残念ながら 1.2 に対応したものはまだないらしい。
(2009-11-22 追記)
CakePHPによる実践Webアプリケーション開発 - miau's blog? にも書いたように、その後 core.po の日本語版が作られています。
CakePHP 1.2 日本語化
■1.2 用の core.po 作ってみる?
どれくらい手間がかかりそうか調べてみた。
・最新のβ(rev6311)で cake i18n とやって生成した core.po には 395 項目あり。
・SVN で最新(rev4387)の core.po には 155 項目あり。
・これを元に rev6311 に適用できるのは 67 項目のみ。残りの 88 項目は使われなくなったのかな?
ということで、328 項目埋める必要がある。大変だ。
/cake/tests とかも入ってるから、これ省いたらもう少し楽かも?でもこれも訳しておいたほうがいいんだろうな、きっと。
■ちょっとやってみた→挫折
項目多いけど、ちょっと集中してやれば数時間でできるんじゃない?ということでやろうとしたんだけど・・・。いきなりやる気なくすような事態が。
まずはトップページの翻訳から取り掛かろうと思ったんだけど、なんだかうまくいかない。よく見たら似たような訳語が何箇所かに出現してて、別のところ編集してた。なんだか
__(〜)
の切り出し方がおかしなことになってるなぁ。
さらに、bake で生成された home.ctp の記述がこんな感じになってた。
echo sprintf(__('To change the content of this page, edit: %s
To change its layout, edit: %s
You can also add some CSS styles for your pages at: %s', true),
APP . 'views' . DS . 'pages' . DS . 'home.ctp.<br />', APP . 'views' . DS . 'layouts' . DS . 'default.ctp.<br />', APP . 'webroot' . DS . 'css');
文末にピリオドとかもちゃんと
__(〜)
に入れてよ。これじゃ .po だけで対応できないよ・・・。
■改行コード
上の例では
__(〜)
の中に改行が混ざってて、.po の中でも
#: /cake/tests/test_app/views/pages/home.ctp:75
msgid "To change the content of this page, edit: %s\n\t\tTo change its layout, edit: %s\n\t\tYou can also add some CSS styles for your pages at: %s"
msgstr ""
こんな感じで \n なんかが入ってる。こうなってると .ctp の改行コードが CRLF のときにうまく翻訳が行われないらしい。(Windows 上の bake で作った home.ctp がこれに相当。)
bake では常に改行コード LF で出力するように変更する、なんて対応も考えられるけど、そもそも改行が入っている長い文を
__(〜)
で囲んでるのが問題な気がする。
とまあ挫折してたんですが、よく見たら上記の例以外は結構まともに翻訳箇所が切り出されているような気がする。
これならまた翻訳試みてもいいかなと思いなおしたんだけど、わざわざ SVN から locale ディレクトリを削除してるところを見ると、まだ翻訳とか始めるなってことかもしれない。
どっちにしろ仕事で必要になったら翻訳を開始せざるをえないので、しばらくは様子見で。