2017-05-19 7 views
0

私は、ユーザーが自分のロケールを変更することができ、それを通してこの方法があります。残念ながらロケールの変更時にURLパラメータを保持する方法は?私のRailsアプリケーションで

# 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 

、ユーザが選択を別のロケール、存在する他のすべてのパラメータnその時点のURLは失われます。それを回避する方法はありますか?

答えて

1

現在、ロケール切り替えツールは、希望のロケールを新しいルートにポストします。そのため、リクエストが送信されたページと、同時にURLの一部が変更されたページにユーザーをリダイレクトすることは非常に難しくなります。

さらに、クエリパラメータを含むURLを指すフォームアクションを設定することはできず、このフォームでgetメソッドを使用してコンテンツを送信することはできません。フォームsubmitは、既存のクエリパラメータをすべて削除し、フォーム内で定義されたキーと値のペアのみを追加するだけです。現在のURLにフォームを送る代わりに、専用のロケールコントローラ

  • フォーム
  • に隠されたタグなど、すべての既存のクエリパラメータを複製

    1. :我々は2つのことを行う必要があり、この問題を解決するには

      RailsヘルパーのネストされたコンテンツタグでサニタイズされたHTMLを避けるために、新しいパーシャルをアプリに追加することをお勧めします。外部の依存関係を削除するには、onchange JavaScriptをインライン化しています。

      # 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 %> 
      

      あなたはこのラインを持つ他のすべてのビューやレイアウトファイルに新しいlocale_switcher部分をレンダリングすることができます

      <%= render 'shared/locale_switcher' %> 
      

      最終ステップ:新しい場合は、リダイレクトをトリガあなたのApplicationContollerからbefore_actionメソッドを追加し、現在のロケールは一致しません:

      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 
      
    関連する問題