I'm trying to insert a locale at the beginning of a request URI in a Rails 3.1 app if it is missing. I created a Ruby script that does what I want:
uri = "/products"
re = /\A\/((?:[a-z]{2,2})(?:[-|_](?:[A-Z]{2,2}))?)(\/.*)\Z/
unless uri =~ re
uri = "/en#{uri}"
end
puts uri
So, if the request URI is /en-GB/products
(the locale is already present), it doesn't do anything. If it is /products
(like the example above), it spits out /en/products
.
Now I'm trying to get it to work in my routes file. Here's what I'v开发者_JS百科e attempted:
match "(*all)", :to => redirect do |params, request|
uri = request.path_info
re = /\A\/((?:[a-z]{2,2})(?:[-|_](?:[A-Z]{2,2}))?)(\/.*)\Z/
unless uri =~ re
uri = "/en#{uri}"
end
"#{request.scheme}://#{request.host_with_port}#{uri}"
end
My problem is that I can't even get inside the match block. I keep getting an ArgumentError: redirection argument not supported
.
I've tried changing it to match "(*all)" => redirect do |params, request|
to no avail.
I'm looking at the Rails 3.1 API documentation for these examples.
Is the routes file the place to try and do this? It makes the most sense to me.
Introducing logic in routes smells for me. Controllers are meant for that, and I would use optional scope in routes and before_filter in controller with redirect_to
routes.rb - keep it simple:
scope '(:locale)', :constraints => {:locale=> /[a-z]{2}(-[A-Z]{2})?/ } do
match 'url1' ...
match 'other' ...
end
controller:
before_filter :check_locale
protected
def check_locale
redirect_to "/en#{request.path_info}" if params[:locale].blank?
end
(the above is written from memory)
I find these lines in a before_filter in the ActionController quite usefull. These lines extracts a locale an redirects e.g. foo.com/fie to foo.com/en/fie (or wahtever locale the current locale is). If the user has a not supported locale, he gets a hint, that he can gon on with english...
def set_locale
params_locale = params[:locale]
if params_locale
if (!Supportedlocale::SUPPORTED.include?(params_locale))
redirect_to "/en/localenotsupported/"
end
end
language_locale = locale_from_accept_language
default_locale = I18n.default_locale
I18n.locale = params_locale || language_locale || default_locale
if params_locale.blank?
redirect_to "/#{I18n.locale}#{request.path_info}"
end
end
def locale_from_accept_language
accepted_lang = request.env['HTTP_ACCEPT_LANGUAGE']
if (!accepted_lang.nil?)
accepted_lang.scan(/^[a-z]{2}/).first
else
"en" #en is default!
end
end
In order to keep parameter like pagination do something like :
def check_locale
if params[:locale].blank?
I18n.locale = :en
redirect_to params.merge!(:locale => I18n.locale)
end
end
So
/controler/action?page=10&search=dada => /en/controler/action?page=10&search=dada
精彩评论