Rails link to current page and passing parameters to it

前端 未结 8 983

I am adding I18N to my rails application by passing the locale using url params. My urls are looking like http://example.com/en/users and http://example.com/ar/users (for th

8条回答
  •  死守一世寂寞
    2020-12-13 00:36

    You can safely use url_for to switch locales with url params if you set only_path: true:

    <%= link_to I18n.t('language_name', locale: I18n.locale), url_for( params.clone.permit!.merge(locale: locale, only_path: true ) %>
    

    We .clone the params before permitting them all (.permit!), to preserve strong parameters elsewhere. The only more secure solution I could find would be to time consumingly whitelist all params instead...


    Robust I18n implementation:

    Add a locales.rb initializer to define what I18n.available_locales you support:

    # config/initializers/locales.rb
    
    # Permitted locales available for the application
    I18n.available_locales = [:en, :fr]
    

    Set a language_name value in each language's locale file (e.g. fr.yml):

    fr:
      language_name: "Français"
    

    As you add more languages, this ERB will let you generically switch between them:

      // app/views/layouts/_languages.html.erb
      
       <% I18n.available_locales.each do |locale| %>
          <% if I18n.locale == locale %>
            <%= link_to I18n.t('language_name', locale: locale), url_for( params.clone.permit!.merge(locale: locale, only_path: true ), {style: "display:none" } %>
          <% else %>
            <%= link_to I18n.t('language_name', locale: locale), url_for( params.clone.permit!.merge(locale: locale, only_path: true ) %>
          <% end %>
        <% end %>
      
    

    For the controller, we automatically find the correct language for the user by detecting their browser's Accept-Language HTTP header (using the http_accept_language gem).

    Set a session cookie to preserve locale across requests.

    Or optionally, use default_url_options to insert the ?locale= param into your app's url. I do both.

    Controller:

    class ApplicationController < ActionController::Base
      before_action :set_locale
    
      private
    
      def set_locale
        I18n.locale = begin
          extract_locale ||
            session[:locale] ||
              http_accept_language.compatible_language_from(I18n.available_locales) ||
                I18n.default_locale
        end
        session[:locale] = I18n.locale
      end
    
      def extract_locale
        parsed_locale = params[:locale].dup
        I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
      end
    
      def default_url_options
        { locale: I18n.locale }
      end
    end
    

提交回复
热议问题