我试图在Rails 3.1应用程序的请求URI开始插入区域设置,如果它缺失。我创建了一个Ruby脚本来做我想做的事情:
uri = "/products"
re = /A/((?:[a-z]{2,2})(?:[-|_](?:[A-Z]{2,2}))?)(/.*)Z/
unless uri =~ re
uri = "/en#{uri}"
end
puts uri
因此,如果请求URI是/en-GB/products
(区域设置已经存在),它不做任何事情。如果它是/products
(如上面的例子),它吐出/en/products
。
现在我试着让它在我的路由文件中工作。以下是我的尝试:
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
我的问题是,我甚至不能进入match块。我一直得到一个ArgumentError: redirection argument not supported
。
我试着把它改成match "(*all)" => redirect do |params, request|
,但无济于事。
我正在查看Rails 3.1 API文档中的这些例子。
路由文件是尝试这样做的地方吗?这对我来说最有意义。
在路由中引入逻辑对我来说很有味道。控制器就是这样做的,我会在路由中使用可选作用域,在控制器中使用redirect_to
的before_filter路线。Rb -保持简单:
scope '(:locale)', :constraints => {:locale=> /[a-z]{2}(-[A-Z]{2})?/ } do
match 'url1' ...
match 'other' ...
end
控制器:
before_filter :check_locale
protected
def check_locale
redirect_to "/en#{request.path_info}" if params[:locale].blank?
end
我发现这些行在ActionController的before_filter非常有用。这些行提取一个语言环境并将其重定向,例如foo.com/fie到foo.com/en/fie(或当前语言环境是什么)。如果用户的语言环境不受支持,他会得到提示,提示他可以继续使用英语…
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
为了保持参数分页,可以这样做:
def check_locale
if params[:locale].blank?
I18n.locale = :en
redirect_to params.merge!(:locale => I18n.locale)
end
end
/controler/action?page=10&search=dada => /en/controler/action?page=10&search=dada