Automatic localized routes using routing filter and user session

I would like to add localization to my rails apps in the prefix form,
fx /:locale/my/other/path/segments

As I understand it, you currently have to do sth like the following

map.resources :books, :path_prefix => ‘/:locale’

and then something like:

book_url(book, :locale => :da)

But I don’t want to have to rewrite all my generated urls!!!
I would like to have the locale stored in the user session (as
retrieved from the route, perhaps using Sven’s routing filter) and
then auto insert the :locale options if it is present, so I don’t have
to rewrite the urls.

filter

  • always store route :locale entry in session[:locale]

book_url(book)

calls ActionDispatch:Routing.url_for

which dispatches to

ActionController::PolymorphicRoutes.polymorphic_url

But I can’t seem to find the :locale option from here either in rails
core or I18n.
Should I simply monkeypatch polymorphic_url and force-add the locale
options to my liking or is there a better way? I thought Rails 3 was
all about avoiding monkeypatches :wink:

Proposed hack of a solution

def polymorphic_url

add default locale from session (retrieved from prefix on route

path)
args << {:locale => session[:locale]} if session[:locale]
send(named_route, *args)
end

Any better ideas or solutions?

As described on Rails Internationalization (I18n) API — Ruby on Rails Guides, you can use
default_url_options for that:

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

2010/3/5 Kristian M. [email protected]:

I just found this:

Which was very old, but at the end had a recent link to this:

http://www.artweb-design.de/2007/5/13/concise-localized-rails-url-helpers-solved-twice

Which at the end proposed this simple solution :slight_smile:

map.with_options(:path_prefix => “:locale”) do |m|
m.resources :posts
m.resources :stories
end

And you have to add before filter to application controller to define
locale, such as

before_filter :define_locale

def define_locale
if params[:locale] == nil
I18n.locale = ‘en’
else
I18n.locale = params[:locale]
end
end

Yeah, I think that could work !!!

This should be a standard feature of Rails 3 as I see it and
documented in the Rails 3 User Guide :wink:
This is how I imagine most people would use localization.

BTW:
I have tried to port the translate_routes to Rails 3. See
http://github.com/kristianmandrup/translate_routes
I still need some help in understanding how to port the old route
segments to the new style, which also supports optional segments.
Please fork my branch and go from there :slight_smile: