Rails I18n set_locale

HaN*_*riX 7 ruby-on-rails internationalization ruby-on-rails-3 i18n-gem

我想通过客户端browserlocale request.env['HTTP_ACCEPT_LANGUAGE']和URL 设置语言环境.

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

  2. 如果用户然后通过语言菜单选择不同的语言,则应将URL更改为例如:myapp.com/de.

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

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

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

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

eta*_*ker 8

我会改变你路线上的一些东西.

第一:

scope :path => ":locale" do
  ... 
end
Run Code Online (Sandbox Code Playgroud)

第二:

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

match '', to: redirect("/#{I18n.locale}")
Run Code Online (Sandbox Code Playgroud)

这似乎是多余的.

我将摆脱该行,只需修改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
Run Code Online (Sandbox Code Playgroud)