关闭

I18n for Rails

标签: railsinternationalizationdictionarylocalization语言accessor
1122人阅读 评论(0) 收藏 举报

作为 Web 的 Framework ,国际化 (Internationalization, i18n) 是不可以不考虑的问题。可是 Ruby on Rails 未有如 Java 的 Resource Bundle在语言层次上支援i18n。如果想要 i18n 又不想自行编写程,可用的方案有 Ruby 的 Gettext 或 Rails 的 Globalize。两者都是很强大的plugin,它们甚至支援 data model 层面的i18n。

可是在我的工作中我可不需要这等威力强大的工具,我只想为我简单的软件的输出加入多语言的功能。我发现 th0fu 在 他的 blog mir.aculo.us 中发表了一个非常简单但功能强大的 Localization 方案,它的优点包括:

 

  • 细小,只用一页程式就为Rails加入l10n支援。
  • 简单,它的做法是extend了Object,为它加入新的方法。使用它作l10n很简单,只需要设定了语言,再把原本的字串"blah"改为用 _("blah") 或 (在rhtml中) <%=_ "blah" %> 表达就行了。

 

他的概念很接近我想要的东西,在他的基础上,我加入了以下改动:

 

  • 使用yml储存资料
  • 利用route和filter功入动态切换语言的功能

 

安装方法很简单:
1. 把 i18n.rb 放到 /PROJECT/lib/ 下

 

代码
  1. # I18n Module    
  2. # License: http://www.apache.org/licenses/LICENSE-2.0.html    
  3. # URL: http://www.reality.hk/articles/2007/02/20/681/    
  4. #    
  5. # Modified from Localization module at mir.aculo.us    
  6. # http://mir.aculo.us/2005/10/03/ruby-on-rails-i18n-revisited    
  7.     
  8. module I18n    
  9.   mattr_accessor :lang    
  10.     
  11.   @@l10s = { :default => {} }    
  12.   @@lang = :default    
  13.     
  14.   def self._(string_to_localize, *args)    
  15.     translated =    
  16.       @@l10s[@@lang][string_to_localize] || string_to_localize    
  17.     return translated.call(*args).to_s if translated.is_a? Proc    
  18.     translated =    
  19.       translated[args[0]>1 ? 1 : 0if translated.is_a?(Array)    
  20.     sprintf translated, *args    
  21.   end    
  22.     
  23.   def self.load    
  24.     loaded = []    
  25.     Dir.glob("#{RAILS_ROOT}/config/lang/*.yml"){ |yml|    
  26.       name = File.basename(yml, ".yml")    
  27.       translate = YAML.load_file(yml)    
  28.       I18n.define(name, translate)    
  29.       loaded << name    
  30.     }    
  31.     return loaded    
  32.   end    
  33.     
  34.   def self.define(lang = :default, dictionary = {})    
  35.     @@l10s[lang] ||= dictionary    
  36.   end    
  37.     
  38.   def self.lang?(lang)    
  39.     @@l10s.key?(lang)    
  40.   end    
  41. end    
  42.     
  43. class I18nFilter    
  44.   def self.filter(controller)    
  45.     usr_lang = controller.request.path_parameters['lang']    
  46.     I18n.lang = I18n.lang?(usr_lang) ? usr_lang : :default    
  47.   end    
  48. end    
  49.     
  50. class Object    
  51.   def _(*args); I18n._(*args); end    
  52. end   

 

2. 在 /PROJECT/config/environment.rb 中加入一句:I18n.load ,这让 I18n 读取 yml 翻译档。

 

代码
  1. Rails::Initializer.run do |config|    
  2.   # Load Localization    
  3.   I18n.load    
  4. end   

 

3. 在 /PROJECT/app/controllers/application.rb 中加入一句:before_filter I18nFilter 。目的是在处理 request 前先查看 request 的 language 再决定 i18n 的输出。

 

代码
  1. # Filters added to this controller will be run for all controllers in the application.    
  2. # Likewise, all the methods added will be available for all controllers.    
  3. class ApplicationController < ActionController::Base    
  4.   before_filter I18nFilter    
  5. end   

 

4. 在 /PROJECT/config/lang/ 下加入yml翻译档。格式是基本的yaml,key: value,很易明白吧?

 

代码
  1. Show: 显示   
  2. Edit: 修改   
  3. Delete: 移除   
  4. Previous page: 上一页   
  5. Next page: 下一页  

 

5. 在 /PROJECT/config/routes.rb 把原本的default route 更改,目的是在网址中加入语言的选项。你可以自行设定 url 的格式,只要把 lang 放到 path 下就行了。

 

代码
  1. ActionController::Routing::Routes.draw do |map|    
  2.   map.connect ':lang/:controller/:action/:id'    
  3. end   

 

6. 在 Application 中把所有字串也转为以下格式:

 

代码
  1. # Call from anywhere (extension to Object class):    
  2. _('blah')    
  3. _('testing %d', 5)    
  4.     
  5. # in .rhtml    
  6. <%=_ 'testing %d', 1 %>   

 

重新启动server后,原本的网址 http://host/PATH 要改为 http://host/LANG/URL。例如输入 http://server/zh-TW/admin 和 http://server/en-US/admin 就可以看见两种语言的网页了 (如果没有设定某个语言,或者某个语言下没有翻译,i18n 会自动输出原本的 key。方便起见通常我都会以英文作 key,那就让系统自动输出英语了。)。

 
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1684113次
    • 积分:20490
    • 等级:
    • 排名:第414名
    • 原创:91篇
    • 转载:1131篇
    • 译文:0篇
    • 评论:146条
    文章分类
    最新评论