Rails link to current page and passing parameters to it

前端 未结 8 926

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:33

    You can parse request_uri, and replace your locale in the path with regular expression

    Ok, here is helper example. If I correctly understand the goal

    def locale_url(url, locale)
      url.gsub(/\/\w*$/, "/#{locale}")
    end
    
    url = "http://www.domain.com/products/1/ru" # or request.request_uri
    locale = "en"
    locale_url(url, locale) #=> "http://www.domain.com/products/1/en"
    

    This is a start point, so you can make some different stuff that you need

    0 讨论(0)
  • 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
      <span class="languages">
       <% 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 %>
      </span>
    

    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
    
    0 讨论(0)
提交回复
热议问题