2017-05-19 12 views
0

In meiner Rails-Anwendung habe ich diese Methode, durch die ein Benutzer ihre locale ändern können:Wie behalten Sie URL-Parameter beim Ändern der Ländereinstellung bei?

# locales_controller.rb 

class LocalesController < ApplicationController 

    def change_locale 
    new_locale = params[:set_locale] 
    if new_locale 
     session[:locale] = new_locale 
     url_hash = Rails.application.routes.recognize_path URI(request.referer).path 
     url_hash[:locale] = new_locale 
     redirect_to url_hash 
    end 
    end 

end 

# routes.rb 

MyApp::Application.routes.draw do 

    scope "(:locale)", locale: /#{DEFINED_LANGUAGES.join("|")}/ do 

    get 'change_locale', :to => 'locales#change_locale' 

    ... 

end 

# application_controller.rb 

class ApplicationController < ActionController::Base 

    before_action :set_locale 

    def set_locale 
    I18n.locale = params[:locale] || session[:locale] || extract_locale_from_accept_language_header || I18n.default_locale 
    session[:locale] = I18n.locale 
    end 

    def extract_locale_from_accept_language_header 
    http_accept_language.compatible_language_from(DEFINED_LANGUAGES) # => e.g. 'de' 
    end 

    ... 

end 

# application_helper.rb 

def locale_switcher 
    form_tag url_for(:controller => 'locales', :action => 'change_locale'), :method => 'get', :id => 'locale_switcher' do 
    select_tag 'set_locale', options_for_select(LANGUAGES, I18n.locale.to_s) 
    end 
end 

Leider, wenn ein Benutzer ein anderes Gebietsschema, alle anderen Parameter, die vorhanden waren, i n der URL zu dieser Zeit sind verloren. Gibt es eine Möglichkeit, das zu umgehen?

Antwort

1

Momentan setzt der Gebietsschemawechsler das gewünschte Gebietsschema auf eine neue Route. Das macht es sehr schwer, den Benutzer zurück zu der Seite zu leiten, von der die Anfrage gesendet wurde, und gleichzeitig Teile der URL zu ändern.

Darüber hinaus ist es nicht möglich, eine Formularaktion auf eine URL zu verweisen, die Abfrageparameter enthält, und dieses Formular sendet seinen Inhalt über die Methode get. Das Formular submit würde einfach alle vorhandenen Abfrageparameter entfernen und nur Schlüssel/Wert-Paare hinzufügen, die im Formular definiert wurden.

Um dies zu beheben, müssen wir zwei Dinge tun:

  1. das Formular an die aktuellen URLs senden anstelle eines dedizierten locale Controller
  2. Duplizieren alle bestehenden Abfrageparameter als versteckte Tags in Form

Um zu vermeiden, HTML in verschachtelten Content-Tags in Rails-Helfer, ich schlage vor, eine neue Teil der App hinzuzufügen. Beachten Sie, dass ich das JavaScript onchange inline eingefügt habe, um externe Abhängigkeiten zu entfernen.

# in app/views/shared/_locale_switcher.html.erb 
<%= form_tag url_for(params), method: 'get' do %> 
    <% request.query_parameters.each do |key, value| %> 
    <%= hidden_field_tag(key, value) 
    <% end %> 

    <%= select_tag(:new_locale, 
       options_for_select(LANGUAGES, I18n.locale.to_s), 
       onchange: 'this.form.submit()') %> 
<% end %> 

Sie können die neuen locale_switcher teilweise in jede andere Ansicht oder Layout-Datei mit dieser Linie machen:

<%= render 'shared/locale_switcher' %> 

Letzter Schritt: Fügen Sie eine before_action Methode zu Ihrem ApplicationContoller, dass eine Umleitung, wenn die neue auslöst und das aktuelle Gebietsschema stimmt nicht überein:

before_action :check_for_locale_change 
before_action :set_locale 

def check_for_locale_change 
    new_locale = params[:new_locale] 

    if new_locale.present? && new_locale != params[:locale] 
    redirect_to url_for(params.merge(locale: new_locale, set_locale: nil)) 
    end 
end 

def set_locale 
    I18n.locale = params[:locale] || session[:locale] || extract_locale_from_accept_language_header || I18n.default_locale 
    session[:locale] = I18n.locale 
end 
Verwandte Themen