6
votes

I am using subdomains to determine the locale in a Rails 4 website. I have this working with a locale switcher exactly the way I want it but now I need to translate the routes and I'm not sure about the best way to proceed.

I have looked the https://github.com/kwi/i18n_routing i18n routing gem but this doesn't work with subdomains, it seems to change the path by adding /locale which is not what I need.

Other gems seem to be out of date with Rails 4.

Edit

Basically I want to be able to use the same view helpers but have the urls change to use whatever language is reflected by the selected sub-domain. this is just about route translation.

I have language specific templates which work and I can produce language spevific navigation templates but I would really like to not have to worry about changing erb path and url erb tags

End edit

A sample from routes.rb

scope module: 'countries', shallow: true do

  get 'south_american', to: 'south_america#index', as: :south_america
  scope module: 'south_america' do
    get 'south-america-weather', to: 'weather#index', as: :south_america_weather
    get 'south-america-gps-maps', to: 'gps#index', as: :south_america_gps
    get 'south-america-accommodation', to: 'hotels#index', as: :south_america_hotels
    get 'south-america-vacations', to: 'vacations#index', as: :south_america_vacations
    get 'south-america-facts', to: 'facts#index', as: :south_america_facts
  end

Using south_america_hotels_path as an example will generate a url for

south-america-accommodation

which is great but how would I translate this so that when I am on the Spanish subdomain south_america_hotels_path will generate the following url

hoteles-en-sudamerica

UPDATE

Also how would this work for a url rather than just a path so that south_america_hotels_url will generate

en.some_site/south-america-accommodation

and when on the spanish subdomain I would get

es.some_site/hoteles-en-sudamerica

and so on for the different locales involved.

I am happy to use yml files for the translations for the urls or to define the additional routes in the routes.rb file, either is an option but I would prefer to define the url's in the routes.rb but I am unable to find a way to provide language specific urls for the same :as path/url option based on subdomain.

Update and further clarification in response to previous replies.

Changing the url's is not an option, they need to match existing url's. I just need to know how to translate them from a view helper point of view without having to change the view helpers.

3
Have you looked at the Rails i18n guide? It explains how to use subdomains for setting the locale. Translating routes is something that Rails doesn't do out of the box; take a look at rails-translate-routes or route_translator for that.janfoeh
@janfoeh I am totally happy with the way I am handling the subdomains, it is just the route translation that is causing me trouble, The gems you point to are not suitable for my needs. Surely this can be done without the use of a gemjamesc

3 Answers

15
votes

EDIT:

This gem is my recommended way to do it. Supports multiple languages without reloading the routes (Which my example didn't). You have to change very few things but it's more consistent than the code below. route translator

Original answer (not working):

This is what have worked for me, you can try it out, in your routes for example you can put:

AppName::Application.routes.draw do
    get "/#{I18n.t("index")}", :to => "pages#index", :as => "index"
    get "/#{I18n.t("contact")}", :to => "pages#contact", :as => "contact"
end

this will get you the routes in your default locale when you run the app, however in runtime, when you change your locale you need to redraw your routes in order to get the routes for the new locale.

I18n.locale = :es #different locale
AppName::Application.reload_routes!

Assuming your default_locale is :en, this example will take the first routes from:

en:
  index: "index-in-english"
  contact: "contact-in-english"

and when the app reload the routes, it will take the translations from your new locale, in this example from

es:
  index: "index-in-spanish"
  contact: "contact-in-spanish"

This way you it will render pages#index and pages#contact and it'll only change the route, you don't have to touch your code. Hope this helps you

2
votes

From my experience, the domain should not be the only thing that determines the locale. It's so much easier if you just put the current locale into a cookie, so that the User can choose in the end!

Now to the translation-part of your question. I think you should change the way you are using the routing.

If you see the countries as resources, and the actions as a different part, you will make your life easier. The model to_param method can help you with that:

resource :country do
  get :weather, on: :member
  ...
end

That will result in urls like south-america/weather but from my perspective, that is even better in terms of readability and search engine optimization. google used to like paths a lot.

For the different translations of your paths, you could iterate over your domains and provide a translation for each segment: http://guides.rubyonrails.org/routing.html#translated-paths

1
votes

To translate routes in a Rails 4+ app, take a look at the route_translator gem. It allows translating routes and comes with a number of configuration options, such as adding a locale section to the generated paths, or support for subdomain based app.