Search code examples
ruby-on-rails-3urlinternationalizationlocale

Switch language with a URL in Ruby on Rails 3


I have a site in both French and English. I want the user to be able to switch language on the fly when they click a link in the header. Pretty straightforward.

I have followed the Ruby on Rails 3 guide, and I have this:

class ApplicationController < ActionController::Base
before_filter :set_locale
def set_locale
    I18n.locale = params[:locale] || I18n.default_locale
end

protect_from_forgery

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

My routes look like this:

scope "(:locale)", :locale => /en|fr/ do

match 'home' => 'home#index'
match 'home/ajax_twitter' => 'home#ajax_twitter'
match 'equipe' => 'equipe#index'
match 'equipe/sylvain' => 'equipe#sylvain'
match 'equipe/benoit' => 'equipe#benoit'
match 'equipe/stephane' => 'equipe#stephane'
match 'equipe/suemarie' => 'equipe#suemarie'
match 'equipe/regis' => 'equipe#regis'
match 'equipe/fred' => 'equipe#fred'

match 'equipe/callback' => 'equipe#callback'
match 'equipe/auth' => 'equipe#auth'
match 'equipe/ajax_contact' => 'equipe#ajax_contact'

match 'linkedinauth/callback' => 'linkedinAuth#callback'
match 'linkedinauth/init_auth' => 'linkedinAuth#init_auth'

match 'mission' => 'mission#index'
match 'service' => 'service#index'
match 'developmen' => 'developmen#index'

match 'contact' => 'contact#index'

match 'mandats' => 'mandats#index'
end

match '/:locale' => "home#index"

And in my view I do this:

<% if I18n.locale == I18n.default_locale %>
  <%= link_to "English", '/en'%>

<% else %>
  <%= link_to "Français", '/fr'%>

<%end%>

All works well in the home page, but if I try to switch language while I'm in a specific controller, I get returned to the home page. I tried to add this:

<% if I18n.locale == I18n.default_locale %>
  <%= link_to "English", '/en/' + params[:controller]%>

<% else %>
  <%= link_to "Français", '/fr/' + params[:controller]%>

<%end%>

This fixes the controller, but if we are in a specific action and switch language again, I get back to the 'index' of this controller.

My question: What is the best way to deal with this?

I guess I could implement something in the ApplicationController (filter) to check if a controller / action / id is passed and append it to the locale. Or can I do this in the routes.rb?


Solution

  • Oh well, finally found a way I like...

    <% if I18n.locale == I18n.default_locale %>
      <%= link_to "English", { :locale=>'en' } %>
    
    <% else %>
      <%= link_to "Français", { :locale=>'fr' } %>
    
    <%end%>
    

    As simple as this!

    Vive Ruby on Rails!