Hot questions for Using Spree in locale

Question:

I'm trying to internationalize a Rails/Spree app using spree's own spree_i18n gem, but I can't get it to work.

I made a minimal app which recreates the problem here.

To cut a long story short, 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 code in my view which should be translated (<%= t("whatever") %>). But no matter what I do, the text is always output in English.

With some additional code for debugging, I can see that once set_locale is called but while execution is still within the controller, the locale is correct (e.g. if I visit the url /?locale=es, then the puts statement in the above controller code outputs es).

But by the time execution has reached the view, the locale has somehow been reset to en. (E.g. adding <% raise I18n.locale.to_s %> within the view raises "en" as an error message.)

I've opened an issue on Spree's Github because as far as I can tell I've followed their instructions exactly and it's still not working, but I may still be missing something. Why isn't the locale getting set properly?

(Note: I should add that the Spree.t doesn't work either, not just t.)

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


Answer:

Spree I18n gives a way to set default language: on config/application.rb with config.i18n.default_locale = :es

And the possibility of setting the languages to be changed. Perhaps on config/initializers/spree_i18n.rb

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

After that, you can remove set_locale on ApplicationController, because it has no effect.

With this at place, it works like a charm.

Edited:

I change the message of error because I want to be sure that it works:

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

And I add a new product without description. Running the server at 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 the expected.

You can see the source with changes at github

Question:

I am trying to customize Spree_i18n frontend nav-bar locale and am having some issues changing it from a select_tag to a link_to. I am trying to make it appear with only two locales selections EN/CN. What would the best solution for this be?

locale.js

load = function() {
  return $('#locale-select select').change(function() {
    return $.ajax({
      type: 'POST',
      url: $(this).data('href'),
      data: {
        locale: $(this).val()
      }
    }).done(function() {
      return window.location.reload();
    });
  });
};

navbar.html.erb

<li id="locale-select" data-hook>
  <%= form_tag set_locale_path, class: 'navbar-form' do %>
    <div class="form-group">
      <label for="locale" class="sr-only"><%= t(:'i18n.language') %></label>
      <%= select_tag(:locale, options_for_select(supported_locales_options, I18n.locale), class: 'form-control', data: { href: set_locale_path }) %>
      <noscript><%= submit_tag %></noscript>
    </div>
  <% end %>
</li>

Answer:

My custom variant

<%= link_to 'en', spree.set_locale_path(switch_to_locale: :en), method: :post %>

Question:

my SpreeCommerce Shop (2.4, spree_i18n 2.4 ist installed) does not detect the browser language preferences. Just the default language will be displayed.

Language configurations are set on the SpreeCommerce admin page ( Supported Locales and Available Locales).

Any advice would be great.


Answer:

You need to add some logic to your application to set the Rails.locale to one of the locales which you support based upon the request Accept-Language passed in.

This functionality isn't supported directly by spree-i18n, but designed to be implemented by your application.