I18n for Rails

转载 2007年09月25日 22:34:00

作为 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,那就让系统自动输出英语了。)。

 

相关文章推荐

Rails国际化(i18n)

很早就知道国际化,就知道i18n,却不知道是什么原因。原来internationalization(国际化),这个单词的长度是20,然后取其首尾字母,中间省略的字母刚好18个。  选用了Loca...

Rails 大规模 I18n 实践

Rails 大规模 I18n 实践

诗歌rails 之 i18n

所谓的国际化:就是根据特定的locale信息,提取相应的字符串和其它一些东西(比如时间和货币的格式)等等。 显然,有三个问题需要解决: 1. 如何确定locale。 2. 如何保存这...

rails 之 i18n

工作经常会在rails中遇到I18n的相关问题,目前为止,我所使用过的方案有两种,各自有各自的好处。 方案1:使用rails官方自带的I18n,文档链接http://guides.rubyonr...

Java for Web学习笔记(七四):国际化i18n(2)Locale Resolver

SessionLocaleResolver 判断locale,采用HTTP请求的Accept-Language,如果我们希望还能通过其他途径来设定locale,需要Locale Resolver,即解...

Java for Web学习笔记(七三):国际化i18n(1)使用Spring框架MessageSource

一般性了解 我们在JSTL fmt[1]中已经接触过国际化i18n,本地化L10n。使用JSTL fmt(Internationalization and Formatting tag library...

Java for Web学习笔记(七五):国际化i18n(3)异常显示的国际化

问题和解决方法 App因某种原因会抛出异常,我们会记录在log中,同时也要告知用户出了问题,一些错误信息需要显示给用户,这就有国际化的需求。我们不应简单将原始的Exception直接显示给用户: 异...

rails 国际化i18

普通信息国际化到 application.rb 中添加config.i18n.default_locale = 'zh-CN'修改配置文件之后不忘忘记重启 rails 来加载新的配置。 然后的要来添加...
  • li_001
  • li_001
  • 2017年04月08日 12:01
  • 203

jquery.i18n.properties

  • 2015年07月22日 16:31
  • 17KB
  • 下载

i18n eclipse

  • 2014年07月25日 17:17
  • 358KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:I18n for Rails
举报原因:
原因补充:

(最多只允许输入30个字)