rails 之 i18n

来源:互联网 发布:管家婆软件下载地址 编辑:程序博客网 时间:2024/05/16 08:15

工作经常会在rails中遇到I18n的相关问题,目前为止,我所使用过的方案有两种,各自有各自的好处。

方案1:使用rails官方自带的I18n,文档链接http://guides.rubyonrails.org/i18n.html

此方法主要使用了I18n这个Module,而I18n最为重要的两个方法是 translatelocalize 他们的使用十分简单,如下:

I18n.t 'hello' => "translation missing: xxx" 
I18n.l Time.now => "Tue, 12 Nov 2013 05:56:47 pm CST"

解释: 日常国际化做翻译的时候,需要用到t这个方法,如上。这个方法可以在直接使用,而不需要I18n来call.如果你的I18n.locale 没有对应的翻译,那么系统将显示 “translating missing: xxx”的字样。既然这样,你需要做的就是,将对应的翻译的字表(yml文件)事先写好,这样rails就会根据这个字表来做翻译。

具体操作:

配置翻译文件的路径

# in config/initializers/locale.rb# tell the I18n library where to find your translationsI18n.load_path += Dir[Rails.root.join('lib', 'locale', '*.{rb,yml}')]# set default locale to something other than :enI18n.default_locale = :pt

在对应配置路径下面补充对应的yml文件

# config/locales/zh.ymlzh-CN:  hello: 你好

通过以上设置,然后通过I18n.locale="zh-CN" 将本地语言环境切换到中文环境,然后再调用t('hello'),将显示“你好”。

个人点评: 采用官方自带的I18n,无需依赖其他gem, 从而代码维护成本低,版本依赖小,上手更容易,代码容易维护。不过这种方式的缺点也很明显,需要书写大量的yml,这样对于yml文件中的key的命名就很头痛,既要满足hash key的命名语法,又要解决翻译过多带来的命名冲突,所以无奈会引入命名空间,导致yml中key的结构层数太多,会出现很多冗余的翻译。


方案2: 使用gettext来做翻译

1) 添加gem依赖

#I18n supportgem 'i18n'gem 'rails-i18n'gem 'gettext',  :require => false, :group => :developmentgem "gettext_i18n_rails"gem 'gettext_i18n_rails_js', github: 'songjiayang/gettext_i18n_rails_js'gem 'ruby_parser', :require => false, :group => :development

2)执行bundle install 
3) 在项目下建立一个locale/zhCN的文件夹,其中zhCN可以叫任意名字,它表示你要翻译的目标语言。 
4) 执行 rake -T 查看相关命令,命令包括

rake gettext:add_language LANGUAGE=xxrake gettext:find                    # Update pot/po filesrake gettext:pack                    # Create mo-files for L10nrake gettext:po_to_json              # Convert PO files to js files in app/assets/localesrake gettext:store_model_attributes

5) 新建config/initializers/fast_gettext.rb 文件,并配置如下

I18n.default_locale = :enFastGettext.add_text_domain 'app', :path => 'locale', :type => :po,                                :ignore_fuzzy => true, :report_warning => falseFastGettext.default_available_locales = ['en_US','zh_CN']  #all you want to allowFastGettext.default_text_domain = 'app'

6) 执行 rake gettext:po_to_json,此命令会新建app/assets/javascripts/locale//app.js文件。 
7)在application.js中引入gettext

//= require_tree ./locale//= require gettext/all


8) 项目中添加I18n切换的操作,例如

class ApplicationController < ActionController::Base  protect_from_forgery with: :exception  before_filter :set_gettext_locale  protected    def set_gettext_locale      requested_locale = params[:locale] || session[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'] || I18n.default_locale      requested_locale = 'zh_CN' if %w(zh zh-tw zh_tw).include?(requested_locale.downcase)      requested_locale = 'en_US' if %w(en en-gb en_gb).include?(requested_locale.downcase)      locale = FastGettext.set_locale(requested_locale)      I18n.locale = locale      puts I18n.locale      session[:locale] = I18n.locale.to_s    endend

9) 在页面中添加locale,例如在application.html.erb中添加

<html lang = <%= "#{I18n.locale}"%>>

10) 添加需要翻译的语句,并执行翻译 ruby代码中

<%=_('hello')%> 

js代码中:

console.log(__("hello"))

执行 rake gettext:find 分析需要翻译的语句,然后到locale/xxx/app.po文件中去执行翻译即可,翻译完毕后,需要执行rake gettext:po_to_json 将翻译也复制一份到js当中去。

总结: 至此大工告成,可以浏览器中访问http://localhost:3000/?locale=zh测试了, 
这里有一个我写的例子https://github.com/songjiayang/railsi18nexample

参考资料:

  1. https://github.com/grosser/gettexti18nrails

  2. https://github.com/nubis/gettexti18nrails_js

0 0