Fernando Maymone
Fernando Maymone

Reputation: 755

How can I deal with i18n and cookies in a multi-language application in Rails?

I am developing an application that have this scenario:

1- The basic language entire all the app is the en-us. 2- The app has some pages that will use en-ca and fr 3- Im using i18n on the app.

The problem here. I have a language selector in case a page has multiple languages.

This language selector should store the selection of the user on a cookie. If this cookie is present I didnt show the selector in any other page anymore.

The problem. If the User is new, and is trying to render a multi-language page it should select the language.

If the User already selected a language, but in another page theres only english pages, the english page should be rendered and the selector not shown.

If the User already selected a language and the page has multiple-languages, the page rendered should be the one with the selected language.

What is the better approach on this situation? Cookies are enough? Anyone know a gem to deal with?

Any help is appreciated. Thanks

Upvotes: 0

Views: 1541

Answers (1)

cercxtrova
cercxtrova

Reputation: 1673

As @max said in comments, it's better to use the locale parameter, and there is very useful gems to do it very easily.

With routing-filter (https://github.com/svenfuchs/routing-filter) you can prepend your routes with the locale. To do it, you just have to add filter :locale at the top of your routes.

Then, with http_accept_language (https://github.com/iain/http_accept_language) you can quickly manage the locale. In the documentation you can see that you are able to just include HttpAcceptLanguage::AutoLocale but personally I did it like that:

# config/application.rb

config.i18n.available_locales = %w[fr en]
config.i18n.fallbacks = true
config.i18n.default_locale = :fr
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}')]
# ApplicationControler

before_action :set_locale

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

def set_locale
  I18n.locale = params[:locale] || http_accept_language.compatible_language_from(I18n.available_locales)
end

This code will use the locale parameter as I18n.locale, and if you just go to the root, the locale will be the browser's locale.

And to switch between locales you just have to do something like that:

- I18n.available_locales.each do |key|
  - next if key == I18n.locale
  = link_to locale: key do
    = key.to_s.capitalize

The code above iterates through the available locales and generate a link to the current path but with a different locale. And the code in the application_controller will keep this locale as "default".

Upvotes: 1

Related Questions