RouteTranslator is a gem to allow you to manage the translations of your app routes with a simple dictionary format
It started as a fork of the awesome translate_routes plugin by Raúl Murciano and then I made changes as I needed until it became the actual code
Right now it works with all the different flavours of rails3-4(3.0, 3.1, 3.2, 4.0) but I'm planning to make it compatible with rails 2.3 too. I'll see how it goes
- If you have this
routes.rb
file originally:
MyApp::Application.routes.draw do
namespace :admin do
resources :cars
end
resources :cars
end
the output of `rake routes.rb` would be this:
admin_cars GET /admin/cars(.:format) admin/cars#index
POST /admin/cars(.:format) admin/cars#create
new_admin_car GET /admin/cars/new(.:format) admin/cars#new
edit_admin_car GET /admin/cars/:id/edit(.:format) admin/cars#edit
admin_car GET /admin/cars/:id(.:format) admin/cars#show
PUT /admin/cars/:id(.:format) admin/cars#update
DELETE /admin/cars/:id(.:format) admin/cars#destroy
cars GET /cars(.:format) cars#index
POST /cars(.:format) cars#create
new_car GET /cars/new(.:format) cars#new
edit_car GET /cars/:id/edit(.:format) cars#edit
car GET /cars/:id(.:format) cars#show
PUT /cars/:id(.:format) cars#update
DELETE /cars/:id(.:format) cars#destroy
-
Add the gem to your
Gemfile
:gem 'route_translator'
And execute
bundle install
-
Wrap the groups of routes that you want to translate inside a
localized
block:MyApp::Application.routes.draw do namespace :admin do resources :cars end localized do resources :cars end end
And add the translations to your locale files, for example:
es: routes: cars: coches new: nuevo fr: routes: cars: voitures new: nouveau
-
Your routes are translated! Here's the output of your
rake routes
now:admin_cars GET /admin/cars(.:format) admin/cars#index POST /admin/cars(.:format) admin/cars#create new_admin_car GET /admin/cars/new(.:format) admin/cars#new edit_admin_car GET /admin/cars/:id/edit(.:format) admin/cars#edit admin_car GET /admin/cars/:id(.:format) admin/cars#show PUT /admin/cars/:id(.:format) admin/cars#update DELETE /admin/cars/:id(.:format) admin/cars#destroy cars_en GET /cars(.:format) cars#index {:locale=>"en"} cars_es GET /es/coches(.:format) cars#index {:locale=>"es"} cars_fr GET /fr/voitures(.:format) cars#index {:locale=>"fr"} POST /cars(.:format) cars#create {:locale=>"en"} POST /es/coches(.:format) cars#create {:locale=>"es"} POST /fr/voitures(.:format) cars#create {:locale=>"fr"} new_car_en GET /cars/new(.:format) cars#new {:locale=>"en"} new_car_es GET /es/coches/nuevo(.:format) cars#new {:locale=>"es"} new_car_fr GET /fr/voitures/nouveau(.:format) cars#new {:locale=>"fr"} edit_car_en GET /cars/:id/edit(.:format) cars#edit {:locale=>"en"} edit_car_es GET /es/coches/:id/edit(.:format) cars#edit {:locale=>"es"} edit_car_fr GET /fr/voitures/:id/edit(.:format) cars#edit {:locale=>"fr"} car_en GET /cars/:id(.:format) cars#show {:locale=>"en"} car_es GET /es/coches/:id(.:format) cars#show {:locale=>"es"} car_fr GET /fr/voitures/:id(.:format) cars#show {:locale=>"fr"} PUT /cars/:id(.:format) cars#update {:locale=>"en"} PUT /es/coches/:id(.:format) cars#update {:locale=>"es"} PUT /fr/voitures/:id(.:format) cars#update {:locale=>"fr"} DELETE /cars/:id(.:format) cars#destroy {:locale=>"en"} DELETE /es/coches/:id(.:format) cars#destroy {:locale=>"es"} DELETE /fr/voitures/:id(.:format) cars#destroy {:locale=>"fr"}
Note that only the routes inside a
localized
block are translated -
Your I18n.locale will be set up automatically from the url param when it's available. To disable it add this to your controller
skip_around_filter :set_locale_from_url
You can configure RouteTranslator via an initializer or using the different environment config files this. It's done this way:
RouteTranslator.config do |config|
config.force_locale = true
config.locale_param_key = :my_locale
end
- force_locale - Set this options to
true
to force the locale to be added to all generated route paths, even for the default locale. Defaults tofalse
. - hide_locale - Set this options to
true
to force the locale to be hidden on generated route paths. Defaults tofalse
. - generate_unlocalized_routes - Set this option to
true
to add translated routes without deleting original unlocalized versions. Autosetsforce_locale=true
. Defaults tofalse
. - generate_unnamed_unlocalized_routes - Set this option to
true
to add the behavior of force_locale, but with a named default route which behaves as if generate_unlocalized_routes wastrue
, soroot_path
will redirect to/en
or/es
depending on the value ofI18n.locale
. Defaults tofalse
. - locale_param_key - The param key that will be used to set the locale to the newly generated routes. Defaults to :locale
- host_locales - optional hash to set default_locale based on request.host, useful for apps accepting requests from more than one domain. See below for more details.
If you have an application serving requests from more than one domain, you might want to set default_locale dynamically based on which domain the request is coming from.
The host_locales
option is a hash mapping hosts to locales, with full
wildcard support to allow matching multiple domains/subdomains/tlds. Host
matching is case insensitive.
When a request hits your app from a domain matching one of the wild-card
matchers defined in host_locales
, the default_locale will be set to the
specified locale, and that locale will be hidden from routes (acting like a
dynamic hide_locale
option.
Here are a few examples of possible mappings:
RouteTranslator.config.host_locales =
{ # Matches:
'*.es' => :es, # TLD: ['domain.es', 'subdomain.domain.es', 'www.long.string.of.subdomains.es'] etc.
'ru.wikipedia.*' => :ru, # Subdomain: ['ru.wikipedia.org', 'ru.wikipedia.net', 'ru.wikipedia.com'] etc.
'*.subdomain.domain.*' => :ru, # Mixture: ['subdomain.domain.org', 'www.subdomain.domain.net'] etc.
'news.bbc.co.uk' => :en, # Exact match: ['news.bbc.co.uk'] only
}
In the case of a host matching more than once, the order in which the matchers are defined will be taken into account, like so:
RouteTranslator.config.host_locales = { 'russia.*' => :ru, '*.com' => :en } # 'russia.com' will have locale :ru
RouteTranslator.config.host_locales = { '*.com' => :en, 'russia.*' => :ru } # 'russia.com' will have locale :en
If host_locales
option is set, the following options will be forced (even if
you set to true):
@config.generate_unlocalized_routes = false
@config.generate_unnamed_unlocalized_routes = false
@config.force_locale = false
@config.hide_locale = false
This is to avoid odd behaviour brought about by route conflicts and because
host_locales
forces and hides the host-locale dynamically.
Bring it! Send me a pull request, don't worry about styling or small details, I'm open to discussion