Loenvpy
Loenvpy

Reputation: 919

Allow locale switching Rails I18n HTTP_ACCEPT_LANGUAGE

I want to get the language of non sign in user from the browser for this i have this code in my application controller

  def set_locale
    if user_signed_in? && !current_user.language.blank?
        I18n.locale = current_user.language
    else
      I18n.locale = extract_locale_from_accept_language_header

      if user_signed_in? && current_user.language.blank?
        current_user.language = I18n.locale
        current_user.save
      end
    end
  end

  def default_url_options(options={})
    { :locale => I18n.locale }
  end

  private

  def extract_locale_from_accept_language_header
    preferred_language = request.env['HTTP_ACCEPT_LANGUAGE'] || ''
    preferred_language = preferred_language.scan(/^[a-z]{2}/).first
    available_locales= ("en" "fr")
    if available_locales.include?(preferred_language)
      preferred_language
    else
      "en"
    end
  end

Suppose that my Browser language is french this give me http://localhost:3000/fr but the problem is when a non sign in user change language to English and go to another page for example http://localhost:3000/en/users/sign_up the language will change to French so i get http://localhost:3000/fr/users/sign_up and not http://localhost:3000/en/users/sign_up so I'm wondering how can i solve this problem

This is my route file

Update

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

# Catch all requests without a locale and redirect to the default...
  get '*path', to: redirect("/#{I18n.default_locale}/%{path}"), constraints: lambda { |req| !req.path.starts_with? "/#{I18n.default_locale}/" }
  get '', to: redirect("/#{I18n.default_locale}")

Upvotes: 0

Views: 1760

Answers (1)

sjaime
sjaime

Reputation: 1500

I think this would fix your issue:

  def set_locale
    if user_signed_in? && !current_user.language.blank?
        I18n.locale = current_user.language
    else
      I18n.locale = if params[:locale].present?
                      params[:locale] # Here you might want to do some checking to allow only your desired locales
                    else
                      extract_locale_from_accept_language_header
                    end

      if user_signed_in? && current_user.language.blank?
        current_user.language = I18n.locale
        current_user.save
      end
    end
  end

This will give precedence to a specified locale in the URL (en | fr) over the HTTP_ACCEPT_LANGUAGE header.

Upvotes: 2

Related Questions