7

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

  1. 如果用户访问一个网址(如:myapp.com)应该检查HTTP_ACCEPT_LANGUAGE并重定向到正确的网址(如: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 

在我的路线文件我:

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 

的问题是,routesfile最先被执行和HTTP_ACCEPT_LANGUAGE有没有效果,因为当涉及到控制器时,url-param已经被设置。

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

回答

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 
+0

的application_controller不叫,在比赛的'情况 - >所以你最终不能设置地方并没有重定向。至少这是我实施它时发生的事情。 –

+0

我刚刚检查了一个全新的Rails(4.1.0)应用程序,它按预期工作。而不是“匹配”,以:重定向(“/#{I18n.locale}”)''你需要写'get'':重定向(“/#{I18n.locale}”)''。这第一个请求不会使用application_controller.rb – etagwerker

+0

由于某种原因,它不适用于我(在4.0艰难测试这个) - 无论如何,我想出了以下解决方案:http://stackoverflow.com/questions/23188986/应用控制器非存在执行的-时-访问域,而无需重定向 –