<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>func09 &#187; i18n</title>
	<atom:link href="http://www.func09.com/wordpress/archives/tag/i18n/feed" rel="self" type="application/rss+xml" />
	<link>http://www.func09.com/wordpress</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Mon, 06 Feb 2012 04:25:55 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Rails2.2の新機能i18nを使ってみる</title>
		<link>http://www.func09.com/wordpress/archives/262</link>
		<comments>http://www.func09.com/wordpress/archives/262#comments</comments>
		<pubDate>Wed, 12 Nov 2008 15:33:17 +0000</pubDate>
		<dc:creator>haga</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.func09.com/wordpress/?p=262</guid>
		<description><![CDATA[はじめに Rails2.2ではついに国際化が標準で搭載されることになった。 Rails 2.2 リリースノート日本語訳 これまでRuby on Railsで作ったアプリの検証メッセージなどを日本語化する場合は gette [...]]]></description>
			<content:encoded><![CDATA[<h2>はじめに</h2>

<p>Rails2.2ではついに国際化が標準で搭載されることになった。<br /><br /></p>

<p><a href="http://webtama.jp/series/railstips/articles/17">Rails 2.2 リリースノート日本語訳</a><br /><br /></p>

<p>これまでRuby on Railsで作ったアプリの検証メッセージなどを日本語化する場合は
<a href="http://www.yotabanana.com/hiki/ja/ruby-gettext-howto-ror.html?ruby-gettext-howto-ror">gettext</a>を使う方法がデファクトスタンダードだったけれど、正直めんどくさいし、初心者にはとっつきにくかった。<br /><br /></p>

<p>ということで正式版が登場する前にi18nを試してみよう。</p>

<p><span id="more-262"></span></p>

<h2>準備</h2>

<p>まずはプロジェクトを作成してedge版を展開する。</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">% rails sample<br />
% cd sample<br />
% rake rails:freeze:edge</div></div>

<p>次に必要なプラグインをインストールする<br />
localized_datesとi18nを入れる。<br /><br /></p>

<p><a href="http://github.com/clemens/localized_dates/tree/master">http://github.com/clemens/localized_dates/tree/master</a><br />
<a href="http://github.com/mattetti/i18n/tree/master">http://github.com/mattetti/i18n/tree/master</a><br /><br /></p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">% script/plugin install git://github.com/clemens/localized_dates.git<br />
% script/plugin install git://github.com/svenfuchs/i18n</div></div>

<p>次にi18nを初期化してロケールファイルを読み込む処理を用意<br />
config/initializers/init_i18n.rb<br />
というファイルを作成して<br /></p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">I18n.default_locale = 'ja-JP'<br />
LOCALES_DIRECTORY = &quot;#{RAILS_ROOT}/config/locales/&quot;<br />
LOCALES_AVAILABLE = Dir[&quot;#{LOCALES_DIRECTORY}/*.{rb,yml}&quot;].collect do |locale_file|<br />
&nbsp; File.basename(File.basename(locale_file, &quot;.rb&quot;), &quot;.yml&quot;)<br />
end.uniq.sort</div></div>

<p>を記述する。<br /><br /></p>

<p>デフォルトのロケールを日本語にしてconfig/locales/以下にあるロケール名.rb、ロケール名.ymlを読み込む。<br /><br /></p>

<p>次にロケール用のファイルを用意する</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">touch config/locales/ja-JP.rb<br />
touch config/locales/ja-JP.yml</div></div>

<h2>サンプルアプリをscaffoldで作成する</h2>

<p>日本語化の準備ができたのでサクっとscaffoldでメモ帳など作ってみよう。</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">% script/generate scaffold note title:string body:text</div></div>

<p>app/models/note.rbを編集する</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># app/models/note.rb<br />
class Note &lt; ActiveRecord::Base<br />
&nbsp; validates_presence_of :title, :body<br />
&nbsp; validates_uniqueness_of :title<br />
end</div></div>

<h2>確認</h2>

<p>ではサーバを起動して確認してみよう</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">% rake db:migrate<br />
% script/server</div></div>

<div id="attachment_264" class="wp-caption alignnone" style="width: 510px"><a href="http://www.func09.com/wordpress/wp-content/uploads/2008/11/b9abd9359c9801972c24977bdc258170.jpg"><img src="http://www.func09.com/wordpress/wp-content/uploads/2008/11/b9abd9359c9801972c24977bdc258170.jpg" alt="失敗" title="日本語になってない" width="500" height="336" class="size-full wp-image-264" /></a><p class="wp-caption-text">失敗</p></div>

<p>失敗。<br />
翻訳が見つからないそうだ。<br /><br /></p>

<p>config/locales/ja-JP.rb<br /><br /></p>

<p>を以下のように編集して、基本的な翻訳メッセージを用意してやる。</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">{<br />
&nbsp; :'ja-JP' =&gt; {<br />
&nbsp; &nbsp; # date and time formats<br />
&nbsp; &nbsp; :date =&gt; {<br />
&nbsp; &nbsp; &nbsp; :formats =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; :default &nbsp; &nbsp; &nbsp;=&gt; &quot;%Y-%m-%d&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :short &nbsp; &nbsp; &nbsp; &nbsp;=&gt; &quot;%e %b&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :long &nbsp; &nbsp; &nbsp; &nbsp; =&gt; &quot;%B %e, %Y&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :long_ordinal =&gt; lambda { |date| &quot;%B #{date.day}, %Y&quot; },<br />
&nbsp; &nbsp; &nbsp; &nbsp; :only_day &nbsp; &nbsp; =&gt; &quot;%e&quot;<br />
&nbsp; &nbsp; &nbsp; },<br />
&nbsp; &nbsp; &nbsp; :day_names =&gt; %w(日曜日 月曜日 火曜日 水曜日 木曜日 金曜日 土曜日),<br />
&nbsp; &nbsp; &nbsp; :abbr_day_names =&gt; %w(日 月 火 水 木 金 土),<br />
&nbsp; &nbsp; &nbsp; :month_names =&gt; [nil] + %w(1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月),<br />
&nbsp; &nbsp; &nbsp; :abbr_month_names =&gt; [nil] + %w(1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月),<br />
&nbsp; &nbsp; &nbsp; :order =&gt; [:year, :month, :day]<br />
&nbsp; &nbsp; },<br />
&nbsp; &nbsp; :time =&gt; {<br />
&nbsp; &nbsp; &nbsp; :formats =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; :default &nbsp; &nbsp; &nbsp;=&gt; &quot;%a %b %d %H:%M:%S %Z %Y&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :time &nbsp; &nbsp; &nbsp; &nbsp; =&gt; &quot;%H:%M&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :short &nbsp; &nbsp; &nbsp; &nbsp;=&gt; &quot;%d %b %H:%M&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :long &nbsp; &nbsp; &nbsp; &nbsp; =&gt; &quot;%B %d, %Y %H:%M&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :long_ordinal =&gt; lambda { |time| &quot;%B #{time.day}, %Y %H:%M&quot; },<br />
&nbsp; &nbsp; &nbsp; &nbsp; :only_second &nbsp;=&gt; &quot;%S&quot;<br />
&nbsp; &nbsp; &nbsp; },<br />
&nbsp; &nbsp; &nbsp; :am =&gt; '',<br />
&nbsp; &nbsp; &nbsp; :pm =&gt; ''<br />
&nbsp; &nbsp; },<br />
<br />
&nbsp; &nbsp; # date helper distance in words<br />
&nbsp; &nbsp; :datetime =&gt; {<br />
&nbsp; &nbsp; &nbsp; :distance_in_words =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; :half_a_minute &nbsp; &nbsp; &nbsp; =&gt; '30分',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :less_than_x_seconds =&gt; '{{count}} 秒以下',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :x_seconds &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&gt; '{{count}} 秒',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :less_than_x_minutes =&gt; '{{count}} 分以下',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :x_minutes &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =&gt; '{{count}} 分',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :about_x_hours &nbsp; &nbsp; &nbsp; =&gt; '約 {{count}} 時間',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :x_days &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=&gt; '{{count}} 日',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :about_x_months &nbsp; &nbsp; &nbsp;=&gt; '約 {{count}} ヶ月',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :x_months &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=&gt; '{{count}} ヶ月',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :about_x_years &nbsp; &nbsp; &nbsp; =&gt; '約　{{count}} 年',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :over_x_years &nbsp; &nbsp; &nbsp; &nbsp;=&gt; '{{count}} 年以上'<br />
&nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; },<br />
<br />
&nbsp; &nbsp; # numbers<br />
&nbsp; &nbsp; :number =&gt; {<br />
&nbsp; &nbsp; &nbsp; :format =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; :precision =&gt; 3,<br />
&nbsp; &nbsp; &nbsp; &nbsp; :separator =&gt; '.',<br />
&nbsp; &nbsp; &nbsp; &nbsp; :delimiter =&gt; ','<br />
&nbsp; &nbsp; &nbsp; },<br />
&nbsp; &nbsp; &nbsp; :currency =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; :format =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :unit =&gt; '¥',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :precision =&gt; 2,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :format =&gt; '%u%n'<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; },<br />
<br />
&nbsp; &nbsp; # Active Record<br />
&nbsp; &nbsp; :activerecord =&gt; {<br />
&nbsp; &nbsp; &nbsp; :errors =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; :template =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :header =&gt; &quot;{{model}}でエラーが発生しました&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :body =&gt; &quot;以下のメッセージを確認してください:&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; },<br />
&nbsp; &nbsp; &nbsp; &nbsp; :messages =&gt; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :inclusion =&gt; &quot;は、リストに含まれていません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :exclusion =&gt; &quot;は、有効な値ではありません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :invalid =&gt; &quot;は、妥当な値ではありません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :confirmation =&gt; &quot;は、確認できません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :accepted &nbsp;=&gt; &quot;は、入力できません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :empty =&gt; &quot;は、何も入力されていません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :blank =&gt; &quot;は、空白です&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :too_long =&gt; &quot;は、長すぎます ({{count}}文字以下)&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :too_short =&gt; &quot;は、短すぎます ({{count}}文字以上)&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :wrong_length =&gt; &quot;は、桁数が合っていません({{count}}桁必要です)&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :taken =&gt; &quot;は、有効ではありません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :not_a_number =&gt; &quot;は、数字ではありません&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :greater_than =&gt; &quot;は、{{count}}文字を超えて入力されています&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :greater_than_or_equal_to =&gt; &quot;は、{{count}}文字以上入力されています&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :equal_to =&gt; &quot;は、{{count}}と同値です&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :less_than =&gt; &quot;は、{{count}}文字未満です&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :less_than_or_equal_to =&gt; &quot;は、{{count}}文字以下で入力されています&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :odd =&gt; &quot;は、端数が入力されています&quot;,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :even =&gt; &quot;は、偶数が入力されています&quot;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; },<br />
&nbsp; &nbsp; },<br />
&nbsp; }<br />
}</div></div>

<p><img src="http://www.func09.com/wordpress/wp-content/uploads/2008/11/step2.jpg" alt="" title="エラーが日本語化された" width="500" height="307" class="alignnone size-full wp-image-266" /></p>

<p>エラーメッセージが日本語になった！<br />
でもnoteとかTitleとかBodyとか中途半端だ。<br />
Modelの属性名もちゃんと日本語化したい。<br /></p>

<h2>モデルの属性名を翻訳</h2>

<p>config/locales/ja-JP.ymlを以下にように編集して、サーバを再起動する</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ja-JP:<br />
&nbsp; activerecord:<br />
&nbsp; &nbsp; models:<br />
&nbsp; &nbsp; &nbsp; note: ノート<br />
&nbsp; &nbsp; attributes:<br />
&nbsp; &nbsp; &nbsp; note:<br />
&nbsp; &nbsp; &nbsp; &nbsp; title: タイトル<br />
&nbsp; &nbsp; &nbsp; &nbsp; body: 本文</div></div>

<p><img src="http://www.func09.com/wordpress/wp-content/uploads/2008/11/step3.jpg" alt="" title="モデルの属性名が日本語化された" class="alignnone size-full wp-image-267" /></p>

<p>おー、モデルの属性値も日本語化された。<br />
完璧、完璧。<br /><br /></p>

<p>しかし、New Noteとかの文言も日本語化したいと思うのが親心というもの。</p>

<h2>モデル以外の文言も翻訳する</h2>

<p>config/locales/ja-JP.ymlを以下のように編集</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ja-JP:<br />
&nbsp; activerecord:<br />
&nbsp; &nbsp; models:<br />
&nbsp; &nbsp; &nbsp; note: ノート<br />
&nbsp; &nbsp; attributes:<br />
&nbsp; &nbsp; &nbsp; note:<br />
&nbsp; &nbsp; &nbsp; &nbsp; title: タイトル<br />
&nbsp; &nbsp; &nbsp; &nbsp; body: 本文<br />
&nbsp; label:<br />
&nbsp; &nbsp; notes:<br />
&nbsp; &nbsp; &nbsp; new_note: 新しいノートを作成<br />
&nbsp; &nbsp; &nbsp; create: 作成する<br />
&nbsp; &nbsp; &nbsp; back: 前の画面へ</div></div>

<p>そしてapp/views/notes/new.html.erbを</p>

<div class="codecolorer-container text blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;h1&gt;&lt;%= t('label.notes.new_note') %&gt;&lt;/h1&gt;<br />
<br />
&lt;% form_for(@note) do |f| %&gt;<br />
&nbsp; &lt;%= f.error_messages %&gt;<br />
<br />
&nbsp; &lt;p&gt;<br />
&nbsp; &nbsp; &lt;%= f.label :title, t('activerecord.attributes.note.title') %&gt;&lt;br /&gt;<br />
&nbsp; &nbsp; &lt;%= f.text_field :title %&gt;<br />
&nbsp; &lt;/p&gt;<br />
&nbsp; &lt;p&gt;<br />
&nbsp; &nbsp; &lt;%= f.label :body, t('activerecord.attributes.note.body') %&gt;&lt;br /&gt;<br />
&nbsp; &nbsp; &lt;%= f.text_area :body %&gt;<br />
&nbsp; &lt;/p&gt;<br />
&nbsp; &lt;p&gt;<br />
&nbsp; &nbsp; &lt;%= f.submit t('label.notes.create') %&gt;<br />
&nbsp; &lt;/p&gt;<br />
&lt;% end %&gt;<br />
<br />
&lt;%= link_to t('label.notes.back'), notes_path %&gt;</div></div>

<p>ちょっと冗長な気がするけど気にしない気にしない<br />
サーバを再起動して確認すると<br /><br /></p>

<p><img src="http://www.func09.com/wordpress/wp-content/uploads/2008/11/step4.jpg" alt="" title="すべての文言が日本語になった" class="alignnone size-full wp-image-268" /></p>

<p>できたー。<br />
基本はロケールファイルにハッシュで翻訳メッセージを記述していき<br />
tメソッドで呼び出すという感じみたいだ。<br /><br /></p>

<p>gettextほどお手軽ではないけれども、今後スタンダードになっていくのだから今から覚えておいても損はないはずだ。</p>

<h2>ファイル一式</h2>

<p>今回作成したファイル。<br /><br /></p>

<p><a href='http://www.func09.com/wordpress/wp-content/uploads/2008/11/sample.zip'>sample.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.func09.com/wordpress/archives/262/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

