Webサービスの国際化対応(I18N)について

Webサービスもリリース時から国際化対応する時代になってきてます。国際化対応について設計時に考えたことをまとめました。前提としているWeb Application FrameworkはRuby on Railsです。大きく、言語、フォーマット、デザインの3つに分けてます。

言語

I18Nという時に一番最初に思いつくのが、言語の切替です。Rails3ではI18nというモジュールが使えるのでそれを利用します。RailsI18nに関してはRails Internationalization (I18n) API が一番まとまっているので参照して下さい。

Locale設定

Localeの設定は、ユーザ設定を優先して、設定が無い場合はリクエストヘッダーのHTTP_ACCEPT_LANGUAGE、それも無ければRailsのデフォルト設定言語を使うようにしました。HTTP_ACCEPT_LANGUAGEの取得のためhttp_accept_languageモジュールを利用します。

 # Controller File
before_filter :set_locale
 
def set_locale
  # サービスが対応している言語を指定
  available = %w{en ja}
  I18n.locale = user[:language] || request.preferred_language_from(available) || I18n.default_locale
end
言語ファイルパス/デフォルト言語の設定

config/initializers/locale.rbで設定します。

 # tell the I18n library where to find your translations
I18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]
 # set default locale to something other than :en
I18n.default_locale = :en
翻訳メソッド

翻訳メソッド(I18n.t)はシンボル、文字列どちらも引数にできます。特に名前空間を指定する時は、表記方法にバリエーションがあります。以下の表現はすべて同じです。

I18n.t 'activerecord.errors.messages.record_invalid'
I18n.t 'errors.messages.record_invalid', :scope => :active_record
I18n.t :record_invalid, :scope => 'activerecord.errors.messages'
I18n.t :record_invalid, :scope => [:activerecord, :errors, :messages]

名前空間の指定のしやすさを考えると引数は文字列でドット(.)つなぎで統一した方が読みやすいです。

言語ファイル

YAMLruby形式どちらも利用できます。どちらを使うべきでしょうか。

You may use YAML (.yml) or plain Ruby (.rb) files for storing your translations in SimpleStore. YAML is the preferred option among Rails developers. However, it has one big disadvantage. YAML is very sensitive to whitespace and special characters, so the application may not load your dictionary properly. Ruby files will crash your application on first request, so you may easily find what’s wrong. (If you encounter any “weird issues” with YAML dictionaries, try putting the relevant portion of your dictionary into a Ruby file.)

要は、YAMLの方が書きやすいためよく使われているが、半角スペース、特殊文字の扱いで正しく辞書を読み込めなかった場合に問題になる。ruby形式だと実行時にエラーが発生するため問題に気づきやすいという利点がある、とのこと。言語ファイルにはruby形式を使った方がよさそうです。

フォーマット

日時

言語ファイルでフォーマットを作成しておくと、テンプレートファイルから呼び出すことができます。

# config/locales/ja.yml
ja:
  time:
    formats:
      short: "%Y年%m月%d日"
      long: "%Y年%m月%d日 %H時%M分%S秒"  
# template file
<%= l Time.now, :format => :short %>
姓名

グローバル利用を想定すると、ユーザ登録時に英語表記を必須入力にしておいた方が後々楽です。HTTP_ACCEPT_LANGUAGEが英語以外の場合は、その言語の姓名もオプションで併せて入力できるようにします。言語により姓名の順序が異なります。これはRailsでは考慮されていないので自前で設計が必要です。姓が先か、名が先かを言語ごとに設定しておき、Localeにより順序を切替えます。

フォーマットでいうと住所や通貨も検討しないといけないのでしょうが、今回のサービスの要件に無かったためあまり調査していません。

デザイン

デザインについては調査中です。ピクトグラムの意味の違い、Right to Left言語圏対応、言語による文字幅の違いあたりをもう少し詰めていかないといけないなと思っています。よい文献等ありましたら教えてください(^^;

まとめ

書いてみて思ったのは国際化も作るサービスによって設計方針が変わるという点です。

  • コンテンツがユーザにより生成され、全世界で共通になっていて、UIのみ言語ごとに切り替えられるパターン(例、SNS
  • コンテンツがユーザにより生成され、言語ごとに分けられているパターン(例、オンラインゲームのワールド)
  • サービス側から言語ごとにコンテンツを提供するパターン(例、コーポレートサイト)

今回は一番目のパターンでした。UIのみの切替が前提だったためLocale設定はユーザ設定を最優先にするようにしました。しかし、例えば3番目のコーポレートサイトのパターンの場合であれば、LocaleはURLに埋め込まれている言語を取得して設定する方が普通の設計だと思います。このように作るサービスによって国際化の方針も変わるため、サービスにあわせてベストな戦略をとれることが重要だと思いました。