Rails I18n set_locale

时间:2012-05-02 15:19:08

标签: ruby-on-rails ruby-on-rails-3 internationalization i18n-gem

我想通过客户端browserlocale request.env['HTTP_ACCEPT_LANGUAGE']和网址设置区域设置。

  1. 如果用户访问网址(例如:myapp.com),则应检查HTTP_ACCEPT_LANGUAGE并重定向到正确的网址(例如:myapp.com/en - 如果browserlocale是en)

  2. 如果用户通过语言菜单选择其他语言,则应将网址更改为:myapp.com/de。

  3. 这是我到目前为止所得到的:

    class ApplicationController < ActionController::Base
      protect_from_forgery
      before_filter :set_locale
    
    private
    
      # set the language
      def set_locale
        if params[:locale].blank?
          I18n.locale = extract_locale_from_accept_language_header
        else
          I18n.locale = params[:locale]
        end
      end
    
      # pass in language as a default url parameter
      def default_url_options(options = {})
        {locale: I18n.locale}
      end
    
      # extract the language from the clients browser
      def extract_locale_from_accept_language_header
        browser_locale = request.env['HTTP_ACCEPT_LANGUAGE'].try(:scan, /^[a-z]{2}/).try(:first).try(:to_sym) 
        if I18n.available_locales.include? browser_locale
          browser_locale
        else
          I18n.default_locale
        end
      end
    end
    

    在我的路线文件中,我得到了:

    Myapp::Application.routes.draw do
      # set language path
      scope ":locale", locale: /#{I18n.available_locales.join("|")}/ do
    
        root :to => "mycontrollers#new"
        ...
    
      end
    
      match '*path', to: redirect("/#{I18n.locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }
    
      match '', to: redirect("/#{I18n.locale}")
    end
    

    问题是routes文件首先被执行而HTTP_ACCEPT_LANGUAGE没有效果,因为url-param在控制器时已经设置好了。

    有人有解决方案吗?也许用中间件来解决它?

1 个答案:

答案 0 :(得分:8)

我会改变你路线中的一些东西。

第一:

scope :path => ":locale" do
  ... 
end

第二:

我看到你在这里要做的事情:

match '', to: redirect("/#{I18n.locale}")

虽然看起来多余。

我摆脱了那一行,只修改了set_locale方法,如下所示:

# set the language
def set_locale
  if params[:locale].blank?
    redirect_to "/#{extract_locale_from_accept_language_header}"
  else
    I18n.locale = params[:locale]
  end
end