Ruby & 教學文章 31 Oct 2008 05:33 pm

推到 Twitter!
推到 Plurk!


[Rails] Rails 2.2 的 i18n 實做



Rails 最近終於推出了 2.2 RC 版,這次推出的兩大特點一個是 Thread Safe、一個是內建 i18n( 有閒錢的話可以買 EnvyCast 推出的 Rails 2.2 What's new Video & PDF 一探究竟)。

剛剛幫手上的某 project 一次升上了 Rails 2.2 順便練習如何操作內建的 i18n。

這一篇是步驟(是的,我已經踩過雷了(註)):

1. 安裝 Rails 2.2

- Install
gem install rails -s http://gems.rubyonrails.org -v 2.2.0
- 修改 config/environment.rb

RUBY:
  1. + RAILS_GEM_VERSION = '2.2.0' unless defined? RAILS_GEM_VERSION
  2. - RAILS_GEM_VERSION = '2.1.0' unless defined? RAILS_GEM_VERSION

2. 安裝 plugin

- localized_dates
ruby script/plugin install git://github.com/clemens/localized_dates.git
- 一些簡單的翻譯例子,可從 rails i18n demo app 下載,扔到 config/locales

3. 修改 config 檔
config/environment.rb
在最末加入以下幾行

RUBY:
  1. I18n.default_locale = 'en-US'
  2.  
  3. LOCALES_DIRECTORY = "#{RAILS_ROOT}/config/locales/"
  4. LOCALES_AVAILABLE = Dir["#{LOCALES_DIRECTORY}/*.{rb,yml}"].collect do |locale_file|
  5.   File.basename(File.basename(locale_file, ".rb"), ".yml")
  6. end.uniq.sort

新增 initializers/locale.rb 內置

RUBY:
  1. I18n.load_path += Dir[ File.join(RAILS_ROOT, 'lib', 'locale', '*.{rb,yml}') ]

4. 在 app/controller/application.rb 設置一個 before_filter 設定 locale

RUBY:
  1. before_filter :set_locle
  2.  
  3.     def set_locale
  4.       # update session if passed
  5.       session[:locale] = params[:locale] if params[:locale]
  6.  
  7.       # set locale based on session or default
  8.       I18n.locale = session[:locale] || I18n.default_locale
  9.  
  10.     end

5. 修改 layout 以及放置 demo, 在 app/vies/layout/application.html.erb 找個地方放置

RUBY:
  1. <% form_tag '' do %>
  2.           <%= select_tag("locale", options_for_select(LOCALES_AVAILABLE, I18n.locale
  3.     ), { :index => nil, :onchange => 'this.form.submit()'}) %>
  4.         <% end %>
  5.             <h1><%= I18n.t 'txt.main_title' %><span id="claim"><%= I18n.t 'txt.sub_title
  6.         ' %></span></h1>

這樣就完成了。

註:我是參考 rails i18n app demo 完成的。但是它的 set_locale 那一段有一些問題。load_translations 是 undefined method。

RUBY:
  1. before_filter :set_locale
  2.  
  3.   def set_locale
  4.     # update session if passed
  5.     session[:locale] = params[:locale] if params[:locale]
  6.  
  7.     # set locale based on session or default
  8.     I18n.locale = session[:locale] || I18n.default_locale
  9.  
  10.     # load locale from settings
  11.     @locale_files = []
  12.     ['yml', 'rb'].each do |type|
  13.       locale_file = "#{LOCALES_DIRECTORY}#{I18n.locale}.#{type}"
  14.       if File.exists?(locale_file)
  15.         @locale_files <<locale_file
  16.         I18n.load_translations locale_file
  17.       end
  18.     end
  19.   end

原因出在 demo app 的 rails 是 freeze 當時 trunk 版的,而正式 Rails 2.2 RC 卻把"load_translations"這一段閹掉了。卻沒有人注意到這個問題。envycasts 跟 官方公告 都推薦看這個 demo app,但 demo app 是有地雷的,但卻一直沒人發現。

ihower 討論這件事,ihower 開玩笑的說:「騙子!! 大家都沒有做i18n!!

----
寫完這一篇 blog 才發現這一篇 wiki ,裡面教的是正確的方法。

Creative Commons License

2 Responses to “[Rails] Rails 2.2 的 i18n 實做”


  1. on 02 Dec 2008 at 11:30 pm 1.CFC said …

    話說我仔細看了一下..
    before_filter :set_locale那邊有打錯字:P

  2. on 24 May 2009 at 10:06 pm 2.Blog.XDite.net » 如何入門 Ruby on Rails?(2009) said …

    [...] 7. I18n - 學會怎麼使用與操作 Rails 內建的 I18n [...]

Trackback This Post | Subscribe to the comments through RSS Feed

Leave a Reply