7

Chcę ustawić ustawienia regionalne przez klientów browserlocale request.env['HTTP_ACCEPT_LANGUAGE'] i przez URL.Szyny I18n set_locale

  1. Jeśli użytkownik odwiedza URL (np myapp.com) Należy sprawdzić HTTP_ACCEPT_LANGUAGE i przekierować do właściwego adresu URL (np myapp.com/en - jeśli browserlocale jest en)

  2. Jeśli użytkownik wybierze inny język za pośrednictwem menu językowego, powinien zmienić adres URL na np. Myapp.com/de.

tu jest moje, co mam do tej pory:

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 

W moich trasach pliku mam:

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 

Problem polega na tym, że routesfile zostanie wykonany pierwszy i HTTP_ACCEPT_LANGUAGE ma brak efektu, ponieważ parametr url został już ustawiony, jeśli chodzi o kontroler.

Czy ktoś ma rozwiązanie tego problemu? Może rozwiązać go za pomocą oprogramowania pośredniego?

Odpowiedz

8

Zmieniłem kilka rzeczy na twoich trasach.

pierwsze:

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

drugie:

widzę, co chce zrobić tutaj:

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

Wydaje się jednak zbędne.

bym pozbyć się tej linii i po prostu zmodyfikować metodę set_locale, tak:

# 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 nie nazywa, w przypadku meczu „” -> tak skończyć się nie ustawienie locale i bez przekierowania. Przynajmniej tak się stało, gdy go zaimplementowałem. –

+0

Właśnie sprawdziłem nową aplikację Rails (4.1.0) i działa ona zgodnie z oczekiwaniami. Zamiast 'match '', to: redirect ("/# {I18n.locale} ") musisz napisać' get '', aby: przekierować ("/ # {I18n.locale}") '. To pierwsze żądanie nie będzie używać application_controller.rb – etagwerker

+0

Z jakiegoś powodu nie działa dla mnie (testowałem to na 4.0 trudne) - w każdym razie wymyśliłem następujące rozwiązanie: http://stackoverflow.com/questions/23188986/ kontroler aplikacji-nie-wykonywany-kiedy-uzyskujący-domeny-bez-przekierowania –