Rails2.3.10 に i18n を 文字コード EUC-JP で導入するメモ

i18n文字コード EUC-JP で Rails2.3.10 に導入するメモです。

実験環境

OS CentOS release 5.3 (Final)
Ruby ruby 1.8.6 (2010-02-05 patchlevel 399) [i686-linux
Rails Rails 2.3.10
i18n 0.5.0
文字コード EUC

Rails2.3.10のデフォルトエラーメッセージ

まずは、適当にRailsアプリケーションを作成します。すべてのファイルの文字コードEUC-JPで作成します。

例として、従来の scaffold で吐き出した雛形のエラーメッセージを確認しておきましょう。
サンプルとして model は

class User < ActiveRecord::Base
  validates_presence_of :name                                                                       
end

となっています。


お馴染みのエラー画面ですね。

i18nをインストール

さっそく、i18nをインストールして、エラーメッセージを日本語化しましょう。

% sudo gem install i18n
Successfully installed i18n-0.5.0
1 gem installed
Installing ri documentation for i18n-0.5.0...
Installing RDoc documentation for i18n-0.5.0...

インストールが完了しました。

$KCODEの確認

ロケールファイルを設定する前に、$KCODEを調べましょう。

% script/console
Loading development environment (Rails 2.3.10)
>> $KCODE
=> "UTF8"

UTF8でした、今回は EUC で行ないたいので、文字コードの設定を修正します。config/initializers/encoding.rb ファイルを作成して下記の記述をします。

$KCODE = 'e'

EUCになったことを確認します。

% script/console
Loading development environment (Rails 2.3.10)
>> $KCODE
=> "EUC"

i18nのデフォルトロケールを ja-JP にする

現在のデフォルトロケールを確認

% script/console
Loading development environment (Rails 2.3.10)
>> I18n.default_locale
=> :en

こちらを参考に、config/initializers/locale.rb を作成します。内容は下記です。

I18n.default_locale = "ja-JP"

i18nのデフォルトロケールを確認

% script/console
Loading development environment (Rails 2.3.10)
>> I18n.default_locale
=> :"ja-JP"

この時点で、エラーメッセージの変化を見てみましょう。

翻訳失敗的なメッセージが出ました。

ロケール用のファイルを準備する(validation用メッセージ、日時等のリソース)

こちらの config/locales/ja-JP.rb をほぼそのまま使わせていただきました。以下の diff が修正点です。また、文字コードEUC-JP に変換しています。

@@ -54,7 +54,7 @@
       },
       :currency => {
         :format => {
-          :unit => '\',
+          :unit => '\\',
           :precision => 2,
           :format => '%u%n'
         }
@@ -92,4 +92,4 @@
       },
     },
   }
-}
\ ファイル末尾に改行がありません
+}

この時点での、エラー画面を見てみましょう。

文字化けていますし、{{model}} というのが、出ていて変換されていません。

{{ ... }} の記述が %{} に変わった

こちらを見ると、{{ ... }} ではなく %{ ... } と記述されています。config/locales/ja-JP.rb を vim で以下のように変更します。

:%s/{{/\%{/g
:%s/}}/}/g

これで、エラー画面を見てみましょう。

{{model}} は解消されました。

文字化けを直す(HTMLの文字コード宣言を直す)

app/views/layouts/users.html.erb をよく見てみると、

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="eb">
<head>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />

となっていました。これを euc にしましょう。以下、変更後です。

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
  <meta http-equiv="content-type" content="text/html;charset=euc-jp" />

しかし、これでは文字化けは解消されませんでした。

script/console で確認してみる

どこで、文字化けが発生しているのか、発見する必要があります。まず、script/console で I18n の戻り値を見てみましょう。

% script/console
>> I18n.translate "activerecord"
=> {:errors=>{:messages=>{:empty=>"は、何も入力されていません", :too_long=>"は、長すぎます (%{count}文字 以下)", :equal_to=>"は、%{count}と同値です", :less_than=>"は、%{count}文字未満です", :inclusion=>"は、リ ストに含まれていません", :accepted=>"は、入力できません", :blank=>"は、空白です", :less_than_or_equal_to=>"は、%{count}文字以下で入力されています", :invalid=>"は、妥当な値ではありません", :odd=>"は、端数が入力 されています", :exclusion=>"は、有効な値ではありません", :confirmation=>"は、確認できません", :wrong_length=>"は、桁数が合っていません(%{count}桁必要です)", :greater_than=>"は、%{count}文字を超えて入力されてい ます", :taken=>"は、有効ではありません", :even=>"は、偶数が入力されています", :too_short=>"は、短すぎます (%{count}文字以上)", :greater_than_or_equal_to=>"は、%{count}文字以上入力されています", :not_a_number=>"は、数字ではありません"}, :template=>{:header=>"%{model}でエラーが発生しました", :body=>"以下のメッセージを確認してください:"}}}

ちゃんと、文字化けせず、EUC-JP のターミナルに表示されました。どうやら、レンダリングで文字化けるようです。

HTTPのヘッダを見てみる

Firefoxのアドオン Live HTTP headers でヘッダを見てみると、Content-Type の charset が utf-8 になっていることが分かりました。

文字化けを直す(Content-Typeをeuc-jpにする)

これを直せば、よさそうです。application_controller.rb に下記を記述します。

before_filter :set_charset

def set_charset
  headers["Content-Type"] = "text/html; charset=euc-jp"
end

これで、エラー画面を見てみましょう。

やっと、EUC-JP での表示が出来ました。

ロケール用のファイルを準備する(テーブル名やカラム名のリソース用)

こちらの ja-JP.yml を 下記のように作成します。もちろん、文字コードEUC-JPです。

ja:
  activerecord:
    models:
      user: ユーザ
    attributes:
      user:
        name: 名前

これで、エラー画面を見てみましょう。

i18nを使って、EUC-JPを表示できました。