I18n.locale gets reset to: en between controller and view

I'm trying to internationalize a Rails / Spree app using a native spree_i18n

gem, but I can't seem to get it to work.

I've made a minimal app that recreates the problem here.

To shorten the long story, I have the following code in my ApplicationController:

before_action :set_locale

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

      

And the code in my opinion that should be translated ( <%= t("whatever") %>

). But no matter what I do, the text is always output in English.

With some extra code to debug, I can see that it gets called once set_locale

, but while execution is still in the controller, the locale is correct (for example, if I find the url /?locale=es

, then the statement puts

in the above controller code outputs es

).

But by the time execution reached the view, the locale had somehow been reset to en

. (For example, adding <% raise I18n.locale.to_s %>

in the view raises the "en" message as an error message.)

I opened an issue on Spree Github because as far as I can tell I followed their instructions exactly and still didn't work, but I might still be missing something. Why is the locale not setting correctly?

(Note: I must add that Spree.t

doesn't work either, not only t

.)

EDIT: If you look at the comment on my Github issue, you can see that I got it working. However, I'm 99% sure that my solution is a hack and there is a better method I should use. Bounty goes to someone who can tell me what I'm doing wrong.

+3


source to share


3 answers


Spree I18n allows you to set the default language: on config/application.rb

with config.i18n.default_locale = :es

And the ability to install languages ​​to change. Perhaps onconfig/initializers/spree_i18n.rb

SpreeI18n::Config.available_locales = [:en, :es, :de] 
SpreeI18n::Config.supported_locales = [:en, :es, :de] 

      

After that, you can delete set_locale

on the ApplicationController because it has no effect.

With this in place, it works like a charm.

Edited:

I am changing the error message because I want to be sure it works:



<%= product_description(@product) rescue Spree.t(:product_has_no_description) +
' ' + Spree.t(:action) %>

      

And I add a new product with no description. Running the server on localhost

In English I see: "This product has no description Action"

In Spanish I see: "Este producto no tiene descripción Acción"

In deutsch I see: "Produkt hat keine Beschreibung Aktion"

Exactly expected.

You can see the source with the changes on github

+5


source


It is not clear to me how it Spree

handles localization, but in yours routes.rb

you only mount the engine.

Basically, you should start localizing your application in routes.rb

by adding:

scope "(:locale)", locale: /#{I18n.available_locales.join("|")}/ do
  # routing and engines go here
end

      

Now you need to support params[:locale]

across all requests, so add to your app controller:



def default_url_options(options={})
  logger.debug "default_url_options is passed options: #{options.inspect}\n"
  { locale: I18n.locale }
end

      

Finally, define and set the locale for the current request, depending on your input:

before_filter :set_locale

def set_locale
  if defined?(params) && params[:locale]
    I18n.locale = params[:locale]
  elsif current_user && current_user.language_id.present?
    I18n.locale = current_user.language.code
  elsif defined?(request)
    I18n.locale = extract_locale_from_accept_language_header
  end
  I18n.locale ||= I18n.default_locale
  I18n.locale = :en unless valid_languages.include?(I18n.locale.to_sym)
end

      

+2


source


In app/controllers/application_controller.rb

maybe using/setting

what doesn't work:

before_action :set_locale
def set_locale
    I18n.locale =
    Spree::Frontend::Config[:locale] =
    Spree::Backend::Config[:locale] = :LOCALE
end

      

In core/lib/spree/core/controller_helpers/common.rb

there is also before_filter

called set_user_language

. This filter is called and re-sets the locale to value session[:locale]

, or if not defined, it uses the default locale.

To fix the problem, set session[:locale]

=: LOCALE in your before_filter.

0


source







All Articles