开发者

Rails 3.1 Routes: How to add a locale to beginning of URI when missing?

开发者 https://www.devze.com 2023-04-11 05:32 出处:网络
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:

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
0

精彩评论

暂无评论...
验证码 换一张
取 消