Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #6581 (closed defect: fixed)

Opened 4 years ago

Last modified 4 years ago

ActionController::Routing : transparent support of international URLs

Reported by: yakovlev Assigned to: David
Priority: normal Milestone: 1.x
Component: ActionPack Version: 1.1.6
Severity: normal Keywords:
Cc:

Description

In routes.rb, I'd like to use Russian characters:

map.connect 'журнал/:id', :controller => 'blog'

Unfortunately, Rails won't recognize it (throwing a routing error), because it compares string "журнал" against URL-encoded string "%D0%B6%D1%83%D1%80%D0%BD%D0%B0%D0%BB". A quick solution is to write:

map.connect "#{CGI.escape('журнал')}/:id", :controller => 'blog'

Or, even better, redefine ActionController::Routing::StaticSegment.initialize method in source:trunk/actionpack/lib/action_controller/routing.rb (so we don't have to write the escape code for each static component of each route):

def initialize(value = nil)
  super()
  self.value = CGI.escape(value)
end

However, it's not a complete solution, because it doesn't support regexps. For example, this route definition for alphabetical index won't work:

map.connect 'указатель/:letter',
            :controller   => 'index',
            :requirements => { :letter => /[абвгдеёжзийклмнопрстуфÑÂ
цчшщьыъэюя]/ }

Instead, we need to write something ugly, obfuscated and non-universal like:

map.connect "#{CGI.escape('указатель')}/:letter",
            :controller   => 'index',
            :requirements => { :letter => Regexp.new( '(%s)' % 'абвгдеёжзийклмнопрстуфÑÂ
цчшщьыъэюя'.split('').map{|l| CGI.escape(l)}.join('|') )}

Obviously, rather than CGI.escape static segments and regexps (the latter task being pretty non-trivial in general case), it's better to CGI.unescape the URL before matching routes. This is exactly what needs to be done. Unfortunately, I'm not familiar enough with the Rails source code to fix it myself.

(If you're going to test these examples, don't forget to define $KCODE='UTF-8' in config/environment.rb .)

Change History

12/15/06 23:42:00 changed by nzkoz

  • status changed from new to closed.
  • resolution set to fixed.

(In [5720]) Make config.plugins affect $LOAD_PATH and remove duplication from $LOAD_PATH [James Adam]

Closes #6581 Closes #6842

12/15/06 23:49:50 changed by lazyatom

  • status changed from closed to reopened.
  • resolution deleted.

Oops - I think nzkoz meant to close #6851 here...

(follow-up: ↓ 4 ) 01/23/07 19:07:15 changed by manfred

This works for me in Firefox and Safari, but that might be because these browsers encode the URL for me. Can you verify if this still happening with Rails 1.2?

(in reply to: ↑ 3 ) 01/23/07 19:50:52 changed by yakovlev

Replying to manfred:

Can you verify if this still happening with Rails 1.2?

I just checked my example (Russian alphabetical index) and it works perfectly with Rails 1.2.1! How do I close this ticket while indicating that it is fixed in 1.2.1? (sorry, I'm not familiar with Trac).

01/23/07 20:13:29 changed by manfred

You can close the ticket by saying 'Fixed in current Rails version' or something similar and choosing () resolve as fixed from the from the dropdown in 'Action' box above the buttons.

I've really glad this is fixed btw (:

01/23/07 21:19:25 changed by nzkoz

  • status changed from reopened to closed.
  • resolution set to fixed.

Yeah, That's seriously cool :)

Fixed in 1.2.1