Ruby on Rails网站语言国际化

作者: 老码农不上班 | 来源:发表于2016-09-08 00:45 被阅读289次

涉及到在Git@OSC中的一些应用

Gem

Rails项目双语化的时候需要用到Rails-18nhttp_accept_languageGem

  • rails-i18n
    根据对应的rails版本添加到Gemfile中
    gem 'rails-i18n', '~> 4.0.0' # For 4.0.x
    gem 'rails-i18n', '~> 3.0.0' # For 3.x
    gem 'rails-i18n', github: 'svenfuchs/rails-i18n', branch: 'master' # For 4.x
    gem 'rails-i18n', github: 'svenfuchs/rails-i18n', branch: 'rails-3-x' # For 3.x
    
  • http_accept_language
    这个Gem能够把用户请求发送过来的请求头中把Accept-Language提取出来放在一个数组中。即就是能检测出用户浏览器中设置的语言偏好。
    gem 'http_accept_language'
    

configuration

config/application.rb文件中基本的设置如下

config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] #
config.i18n.default_locale = 'zh-CN'
config.i18n.available_locales = ['zh-CN', 'en', 'zh-TW']
config.i18n.fallbacks = true  #当应用程序需要的语言文件缺失时,使用默认的语言文件default_locale

同时I18n.config.enforce_available_locales默认是true,要改变为true

ApplicationController

用户请求通过路由器发送到对应的action之前应在application_controller中设置好网站的语言种类:
before_filter set_locale

def set_locale
  if cookies[:user_locale] && I18n.available_locales.include?(cookies[:user_locale].to_sym)
    l = cookies[:user_locale].to_sym
  else
    l = http_accept_language.compatible_language_from(I18n.available_locales)
    cookies.permanent[:user_locale] = l
  end
  I18n.locale = l || I18n.locale
end

Git@OSC网站国际化的策略是:首先读取用户的浏览器中是否包含语言设置的cookie(下文会涉及到把语言设置的cookie写到用户浏览器中)并且判断网站是非提供该语言;如果不满足上诉判断,则通过http_accept_language获取用户浏览器对语言设置的偏好,并且与网站中提供的语言匹配出来之后设置到用户浏览器的cookie中,以便下次读取用户的请求中判断是否包含已经设置的语言种类。

用户主动选择网站的语言

国际化的网站中都有语言列表供用户选择,这是用户主动根据自己的语言偏好设置对此网站进行访问。
Git@OSC对此的实现是这样的:

  • 在view中
    = link_to change_locale_path(locale: "zh-CN"), class: "ui button text-left" do
      %i.china.flag
      中文简体
    = link_to change_locale_path(locale: "en"), class: "ui button text-left" do
      %i.us.flag
      English
    
    那么用户选择了语言之后经过路由
  • 在routes中
    get '/language/:locale', to: 'home#language', as: :change_locale
    
    不言而明,经过路由分发之后由home_controller的language action处理用户请求。
  • 在控制器中
    def language
      l = params[:locale].to_s.strip.to_sym
      l = I18n.default_locale unless I18n.available_locales.include?(l)
      cookies.permanent[:user_locale] = l
      if request.env["HTTP_REFERER"].present?
        redirect_to :back
      else
        redirect_to '/'
      end
    end
    
    可以看出还会把语言设置写入用户的浏览器cookie,以便下次用户访问的时候能记住其语言偏好。
    以上就是用户主动选择语言种类时的后端处理。

view、controller、model、xxx.js.coffee中对语言配置文件的读取

rails项目config/locals目录下有各种语言以及Gem对应的语言版本配置文件,这些配置文件中rails项目各个模块中的引用不进相同。

  • view controller
    例如Git@OSC个人主页中的“加载更多”可以这样子写 #{t('dashboard.active.loading_more_none')}
    例如Git@OSC新建项目成功时控制器返回的flash消息 flash[:notice] ="#{t('flash.new_repo_success')}"

  • model
    在model中对语言文配置文件的读取与前面不同。
    例如Git@OSC中“观察者”,“开发者”,“管理员”这些角色字眼写在model中,此时对于语言配置文件的读取应是这样I18n.t('reporter') => REPORTER

  • xxx.js.coffee
    写rails项目时很多时候经常把js单独写在与coffeescript文件中,那么rails中的ruby实例变量(在这里指的是从语言配置文件读取文件是产生的实例变量)如何与coffee script使用呢?其实有个gon这样的Gem,他们的自定义是

    Your Rails variables in your JS

    明白了吧?下面我们来看看如何使用。

    • = include_gon
      这个推荐写在布局文件中,如果网站的header单独写在一个模版中,那么= include_gon写在这个模版中再好不过了。
      - 在controller action中编写gon变量
      视图渲染之前是一定是经过某个action(这里不包括nginx缓存前端模版啥的)那么在xxx.js.coffee想要使用rails项目中的变量就显得容易了,结合gon我们只在这对应的action中生成这个变量即可,举个例子。
      Git@OSC项目主页中一键有克隆仓库地址的操作,然后有个popup提示用户“复制”或者“已复制”,这些都是写在coffscript文件中的。project_controller show action渲染项目主页,由此我们可以在此action中这样写:
      gon.cp = "#{t('gist.copy')}"
      gon.aready_cp = "#{t('gist.already_copy')}"
      
    • xxx.js.coffee中需要国际化文字
      结合上面写的举个例子比较明显
      clip_holder.popup content: gon.aready_cp
      
      直接gon.aready_cp就可以了,方便吧。

网站中时间的国际化

不推荐使用rails的time_ago_in_words帮助方法。原因为这事后端渲染导致了一个问题。比如你打开一个网页,显示的是一分钟前,然而不关闭次网页,一段时间之后应比一分钟之前的“一分钟之前”还要长了,但是后端渲染无法做到动态改变此时间。那么timeago就应运而出现。
添加必要的jquery.timeago.js"这里有各种国际语言供你选择jquery-timeago
首先封装一个帮助方法以便我们在视图中使用app/helpers/time_helper.rb

module TimeHelper
  def timeago(time)
    content_tag(:span, time.iso8601, title: time.iso8601, class: 'timeago')
  end
end

然后在application.js中加入

$('.timeago').timeago()

最后就可以在视图中使用了

"posted #{timeago(post.created_at)} #{t('ago')}"

缓存相关

在rails项目中,国际化的网站有多少中语言就有多少套缓存文件,自然而然我们想到了用不同语言对应的键区分开来。

  • 在ApplicationController中写个帮助方法获取当前用户设置的语言偏好
    helper_method :getlocal
    
    def getlocal
      I18n.locale.to_s
    end
    
  • 生成缓存键的时候加上getlocal
    例如在视图中生成的建[@project.id, '@tree_readme@', @path, tree.readme.id, getlocal].join(':')

相关文章

  • Ruby on Rails网站语言国际化

    涉及到在Git@OSC中的一些应用 Gem Rails项目双语化的时候需要用到Rails-18n和http_acc...

  • Rails[2]:学习资源

    Rails的全名是Ruby on Rails,也会简称ROR。Rails是用ruby语言编写的一个web应用开发框...

  • rails 学习

    试一下,先拷贝一段 Rails的全名是Ruby on Rails,也会简称ROR。 Rails是用ruby语言编写...

  • mac 终端

    ruby,gem,rails之间的关系? Ruby是一种脚本语言,Gem是基于Ruby的一些开发工具包,Rails...

  • 课堂小计

    要学习的语言 语言:ruby on rails 参考网址:https://zh.wikipedia.org/wik...

  • 适合rails学习的项目源码阅读

    rable 社区网站,类似于V2EX ruby-chain 社区 shopqi 电商网站 rails...

  • You should use PG::Connection, P

    $ rails -v Rails 4.2.6 $ruby -v ruby 2.3.1 1.Gemfile -sou...

  • Ruby小白进化之路

    # Ruby on Rails

  • Rubygem 项目敏感数据的管理

    既然要说 Ruby 那肯定是离不开 Rails 的,毕竟 Ruby 只是 Ruby on Rails 的一套框架,...

  • Introduction

    Ruby on Rails 是一种让开发,部署和维护网站应用轻松的框架。在初始版本发布后的几个月间,Rails 从...

网友评论

    本文标题:Ruby on Rails网站语言国际化

    本文链接:https://www.haomeiwen.com/subject/uklsettx.html