Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby on Rails Routes with Locales

I am using this guide: http://edgeguides.rubyonrails.org/i18n.html

What I would like:

/about goes to pages#about with the defaulted locale of en.

/en/about goes to pages#about with the locale of en.

/es/about goes to pages#about with the locale of es.

What I get:

/about goes to root_path with the locale of about.

/en/about goes to pages#about with the locale of en.

/es/about goes to pages#about with the locale of es.

Here is some code:

# config/routes.rb
match '/:locale' => 'pages#news'

scope "(:locale)", :locale => /en|es/ do
  match '/abcd' => 'pages#abcd'
  match '/plan' => 'pages#plan'
  match '/about' => 'pages#about'
  match '/history' => 'pages#history'
  match '/projects' => 'pages#projects'
  match '/donate' => 'pages#donate'
  match '/opportunities' => 'pages#opportunities'
  match '/board' => 'pages#board'
end

root :to => "pages#news"

# app/controller/application_controller.rb
before_filter :set_locale

def set_locale
  # if params[:locale] is nil then I18n.default_locale will be used
  I18n.locale = params[:locale]
end

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

If I am reading the guide correctly, section 2.5 says that I should be able to access /about and have it load the default locale.

From 2.5:

# config/routes.rb
scope "(:locale)", :locale => /en|nl/ do
  resources :books
end

With this approach you will not get a Routing Error when accessing your resources such as http://localhost:3001/books without a locale. This is useful for when you want to use the default locale when one is not specified.

like image 771
tinifni Avatar asked Dec 20 '10 05:12

tinifni


3 Answers

The first line in your routes.rb is a catch-all route

match '/:locale' => 'pages#news'

It should be the last line in the file, right after the root route.

like image 182
jhlllnd Avatar answered Nov 14 '22 01:11

jhlllnd


The other way is:

Possible_locales = /en|es/

match '/:locale' => 'pages#news', :locale => Possible_locales

scope "(:locale)", :locale => Possible_locales do
   ...
end

No need to worry about routes order.

like image 29
bkmn Avatar answered Nov 13 '22 23:11

bkmn


This blogpost explains it actually in great detail (Rails 4):

Just what I was looking for when nothing seems to work

http://dhampik.com/blog/rails-routes-tricks-with-locales

  scope "/:locale", locale: /#{I18n.available_locales.join("|")}/ do
    resources :posts    
    root to: "main#index"
  end

  root to: redirect("/#{I18n.default_locale}", status: 302), as: :redirected_root

  get "/*path", to: redirect("/#{I18n.default_locale}/%{path}", status: 302), constraints: {path: /(?!(#{I18n.available_locales.join("|")})\/).*/}, format: false

Redirects to default lang from root and does a lot of other things as well.

like image 45
mahatmanich Avatar answered Nov 14 '22 00:11

mahatmanich