Rails i18n の対応と反省点

| コメント(0) | トラックバック(0)

つい最近 Rails を使った多言語対応のソーシャルゲームアプリを作ったので、自分のメモがてら、気をつけた方が良さそうなポイントを残しておきます。 (今現在も開発進行中ですが) 割と最近見つけたんだけど、このエントリがコンパクトにまとまっていて、 i18n のエントリポイントとしては最適な気がしました。

Railsの多言語化対応 i18nのやり方を整理してみた!【国際化/英語化】 - 酒と泪とRubyとRailsと

このエントリが非常に良いので、流れに沿った形で僕の反省点などを書いていこうと思います。

  • i18n.l は積極的に使ったほうがいいです

日付時刻情報を
Time.now.strftime('%Y/%m/%d %H:%M:%S')
とかして strftime 関数で表示整形するケースがあるかと思いますが、以下の2つの理由から i18n.l を最初から使うことを勧めます。「日付を整形してくれます」くらいのノリで捉えるのはもったいない!!

  1. 24時制が一般的に受け入れられるのは日本だけ
  2. 日米で一般的な「月日」の表記は欧州では逆に「日月」

アメリカでは24時制の表記は military time と呼ばれていて、特殊な業種でしか使わないそうですし、英語ネイティブのスタッフからも「一般ユーザーに分かりにくいから、12時制表記にできないか?」とリクエストを受けました。
韓国人の同僚に「バトルの開始は20時からっていうのと、午後8時からっていうの、どっちが一般的?」と聞いても、同じように「午後8時、の方が普通ですね」と言われたので、ちゃんと合わせた方がいいと思います。多分、電車やバスの時刻表が24時制で書いてあるので、僕ら日本人の方がマヒしちゃってるんでしょうね。

2つ目の理由の月日の表記ですが、日本では11月12日を 11/12 と書きますし、米国でも 11/12 ないしは Nov. 12 で通ります。これがドイツやフランスでは 12/11 や 12 novembre のように日の方が月よりも先に来るのが一般的だそうです。source
ですので、 strftime 関数で順番を決め打ちにして整形するよりも、日時表記のフォーマットを .yml ファイルに追い出しておく方が良いです。

  • snippet 登録しておくと楽

.erb のファイル内で大量に <%= t('foo.hoge') %> という記述をすることになるので、 yasnippet に以下のようなスニペットを登録して、キーバインド一発で入力できるように工夫していました。

# -*- mode: snippet -*-
# name: <%= t('.***') %>
# --
<%= t('.${key_name}') %>$0
  • yml のキーに _html を必要に応じて付ける & YAML への切り出しを大きめに

例えば

en:
  view:
    hello: '<span class="foo">Hello</span>'

とかしておくと、 value 部がいい感じにエスケープされて出力されます。一見メリット無さそうにも見えますが、日本語とヨーロッパ系の言語では語順が逆になるケースが多いので、HTMLをかなり広めの範囲でばっくりと .yml ファイルに追い出した方が辻褄を合わせやすいケースが多々ありました。

以下の例では説明の為に単純化していますが、

<font color="yellow">%{item_name}</font>を発見した!!

というのを i18n 対応する場合、目的語と動詞の語順が逆になることを見越して、YAMLファイルへの切り出しを大きめに

ja:
  view:
    item_found_html: '<font color="yellow">%{item_name}</font>を発見した!!'

のように書いておけば、英語版は

en:
  view:
    item_found_html: 'Found <font color="yellow">%{item_name}</font>!!'

とすることができます。
「を発見した!!」って文字列だけを i18n.t の対象にしようとすると上手く行かない(.erb側の修正も必要で、それなりに厄介)ので、最初っからこうしておいたほうが良いです。
(これは単純化している例なのでアレですが、実際にはもっともっと複雑です)

  • クォートの問題

英語だと you are を you're としたり、 Let's などの言い回しでアポストロフを多用します。上記の例では "Found xxx !!" という文字列だけだったのでセーフでしたが、文言中にアポストロフが出てくると、 ' (半角シングルクォート)で表記されるので、非常に厄介です。(この場合、 YAML のパースエラーが起こって、 Rails サーバーが起動すらしなくなる) この厄介な問題に対するベストプラクティスはまだ見つけられていませんが、少なくとも YAML ファイル内で使うクォートと、参照元のクォートは、プロジェクトで統一すべきです。プロジェクトで統一さえされていれば、 YAML ではシングルクォートを重ねることで('' と書く)エスケープができますし、あるいは &#39; という書き方にすることもできます。

  • 辞書ファイルの分割は、翻訳者に配慮して!

リンク先のエントリにもあるように、僕らのプロジェクトでも view ごとにファイルを分けて、 models というディレクトリも作っていました。 Rails エンジニア的にはこれが最も自然で、直感的に感じられる良い管理方法でしょうが、翻訳者の目線で見ると色々と問題があります。
というのも、ある程度の規模以上の商用サービスになるとテキスト量がそれなりに大量になります。(原稿用紙換算で数百枚〜)その大量のテキストを全て Rails エンジニア、ないしは Rails を理解している人が翻訳するならいいんですが、さすがに物量が多すぎるのでプロの翻訳者をアサインしました。幸いな事に、翻訳者の方が yml ファイルをサポートしている翻訳ツールを使っている、ということだったので、「じゃぁ en.yml ファイルの作成までお願いしますね」という形で作業を進めたんですが、 views や models というフォルダ構成は、翻訳者目線で見ると意味が無いんですね。
例えばショップ画面みたいなのを例に上げると、使い方の説明テキストは views/shop/ja.yml に書いてあるのに、なぜかエラーメッセージが見つからない。画面には確かに表示されているのに!
検索機能を使って探してみると models/shop/en.yml の方にある!ってなことが起こります。

翻訳対象のテキスト量と、スタッフのアサインにもよるので一概にどうするのがベスト、とは割り切れないと感じていますが、少なくとも Rails のことをあまり良く知らない翻訳のプロと共同作業する場合は、翻訳者が迷わないで済むような進め方を採る方が効率的かと思いました。

  • locale 別のテンプレート

将来的なアップデートのことを考えると、緊急避難的な手法に留めておく方が吉かと。
もちろん、使えるシーンでは活用したほうが良いんでしょうが、あまり更新頻度の高い所で使うのは避けたほうが良いかと感じています。

言語ごとにサーバーを分けるのが楽 :)

  • あまり触れられていない、画像などの対応

テキストの翻訳も当然必要なんですが、それ以上に厄介なのが画像注に含まれている文字情報の翻訳でした。
まず、一般的な WEB で使われる png 画像や jpeg 画像は「出力された結果」であり、元の psd ファイルなり ai ファイルが存在しているハズ、です。画像中のテキスト翻訳のポイントは、「出力元のファイルを如何に簡単に探し出せるか」にかかっています。こういった画像の作成は大抵の場合、 Rails エンジニアではなくデザイナさんが管理していると思うので、連携を密にしておく必要があります。

生成された png / jpeg 画像の配置場所と、コードからの参照方法ですが、フォルダ構成を

  1. assets/images/ja
  2. assets/images/de
  3. assets/images/en

などのようにしておき、参照側で locale を判別して振り分ける方法も可能でしょう。しかしこの方法だと、テキストを含まない画像を、全ての locale ごとのディテクトリに多重に保持するか、あるいはテキストを含む画像かどうかを参照元のコードが意識しないといけないため、あまり効率的とは言えません。さらに、画像量が増える & それを全部デプロイするため assets precompile する時間が無駄に長くなる可能性もあります。
今回作ったアプリでは、幸いにも言語ごとにサーバー環境を分けることができたので、上記の方法は採らず、以下のようなディレクトリ構成にしました。

  1. images/sp ← 画像が全て入ってる。画像中のテキストは日本語
  2. images/sp_en ← テキストを含む画像を、英訳したものだけが入っている
  3. images/sp_de ← テキストを含む画像を、ドイツ語訳したものだけが入っている

基本的に画像は全て images に入っていて、2 と 3 の英語用、ドイツ語用のフォルダには、文字を含まない画像は一切入っていません。なので、ローカライズされた画像をサーバーに上げるために、英語版のサーバーにデプロイする時には images_en 以下の画像で images を上書きする、というタスクを capistrano に追加してあります。
タスクはだいたいこんな感じです。


  task :overwrite_localized_images do
    run "if [ -d #{release_path}/app/assets/images/sp_en ]; 
        then rsync -avz #{release_path}/app/assets/images/sp_en/ #{release_path}/app/assets/images/sp/; fi"

今のところ、このやりかたで問題なく動作していますが、日本版ではこのタスクを実行した後に rm -rf sp_en してから assets precompile しないといけない、などの細かい課題が残っている感じです。

  • テキストが枠に入りきらない

目下、鋭意対応中なのがこの問題で、単純に「漢字文化すげぇ!」ってことに尽きると感じています。というのも、日本語だと二文字で 攻撃 で済んでいたボタンのラベルが、英語だと Attack になる。このボタンが最初から英語の文字幅を考慮して作成されていれば問題ないですが、そうは行かないんですねぇ。

さらに英語以外の言語も増やすと、問題は複雑度を増します。

日本語 :確率 英語  : Probability ドイツ語:Wahrscheinlichkeit

幅だけで言うと、ドイツ語は単語によっては日本語の3倍近く長くなるものもあるので、ゲームのようにレイアウトにシビアな案件で i18n する場合は、ドイツ語を基準にレイアウト作ったらいいんじゃないかと思います。

参考:http://nlab.itmedia.co.jp/nl/articles/1209/06/news083.html

トラックバック(0)

トラックバックURL: http://somethingnew2.com/cgi/b/mt-tb.cgi/1270

コメントする

この記事について

このページは、SATO Yozoが2013年11月12日 23:00に書いた記事です。

ひとつ前の記事は「Mac OS X で Desktop の順番が勝手に入れ替わるのを止める」です。

次の記事は「Install Clojure on MacBook」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 6.1.2