ОК, мне удалось решить эту проблему:
По умолчанию это невозможно сделать в Rails (по крайней мере, пока). Вместо использования пространств имен и значений по умолчанию мне нужно было установить фильтр маршрутизации Свена Фукса .
После установки плагина я добавил следующий файл в мою директорию lib:
require 'routing_filter/base'
module RoutingFilter
class Locale < Base
# remove the locale from the beginning of the path, pass the path
# to the given block and set it to the resulting params hash
def around_recognize(path, env, &block)
locale = nil
path.sub! %r(^/([a-zA-Z]{2})(?=/|$)) do locale = $1; '' end
returning yield do |params|
params[:locale] = locale || 'en'
end
end
def around_generate(*args, &block)
locale = args.extract_options!.delete(:locale) || 'en'
returning yield do |result|
if locale != 'en'
result.sub!(%r(^(http.?://[^/]*)?(.*))){ "#{$1}/#{locale}#{$2}" }
end
end
end
end
end
Я добавил эту строку в route.rb:
map.filter 'locale'
Это в основном заполняет хук до и после, генерируемый плагином, который оборачивает маршрутизацию рельсов.
Когда URL-адрес распознан, и до того, как Rails что-то с ним сделает, вызывается метод around_recognize. Это извлечет двухбуквенный код, представляющий локаль, и передаст его в параметрах по умолчанию 'en', если локаль не указана.
Аналогичным образом, при создании URL-адреса параметр локали будет вставлен в URL-адрес слева.
Это дает мне следующие URL и сопоставления:
/ => :locale => 'en'
/en => :locale => 'en'
/fr => :locale => 'fr'
Все существующие помощники URL работают как прежде, с той лишь разницей, что, если не указан языковой стандарт, он сохраняется:
home_path => /
home_path(:locale => 'en') => /
home_path(:locale => 'fr') => /fr