使用可选路径前缀创建路由

如何让我的路由识别可选的前缀参数,如下所示:

/*lang/controller/id 

因为lang部分是可选的,并且如果未在URL中指定,则具有默认值:

 /en/posts/1 => lang = en /fr/posts/1 => lang = fr /posts/1 => lang = en 

编辑

理想情况下,我希望通过映射命名空间来跨多个控制器和操作执行此操作:

 map.namespace "*lang" do |lang| lang.resources :posts lang.resources :stories end 

好的,我已经成功解决了这个问题:

默认情况下,在Rails中无法做到这一点(至少现在还没有)。 我需要安装Sven Fuchs的路由filter ,而不是使用名称空间和默认值。

安装插件后,我将以下文件添加到我的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 

我将此行添加到routes.rb:

 map.filter 'locale' 

这基本上填充了插件生成的前后挂钩,它包裹了导轨路由。

当识别出一个url,并且在Rails开始对它做任何事情之前,会调用around_recognize方法。 这将提取一个代表语言环境的双字母代码,并在params中传递它,如果没有指定语言环境,则默认为'en'。

同样,当生成url时,locale参数将被推送到左侧的URL中。

这给了我以下url和映射:

 / => :locale => 'en' /en => :locale => 'en' /fr => :locale => 'fr' 

所有现有的url助手都像以前一样工作,唯一的区别是除非指定了语言环境,否则它将被保留:

 home_path => / home_path(:locale => 'en') => / home_path(:locale => 'fr') => /fr 

您可以使用:defaults键定义路径中的:defaults 。 试试这个:

 map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :defaults => { :lang => 'en' } 

我理解这个老问题,但它可能有用。

  map.with_options(:path_prefix => ":locale") do |m| m.resources :posts m.resources :stories end 

并且您必须在filter之前添加到应用程序控制器以定义区域设置,例如

 before_filter :define_locale def define_locale if params[:locale] == nil I18n.locale = 'en' else I18n.locale = params[:locale] end end 

我猜测(现在没时间测试)这可能有效:

 map.connect ':language/posts/:id', :controller => 'posts', :action => 'show' map.connect 'posts/:id', :controller => 'posts', :action => 'show' 

好的,尝试过 – 它至少可以在Rails 2.1.1上运行。 这很好。 但是,无法获得:默认的想法,这是一种耻辱,因为它是DRYer。

您可以一次使用[key] => nil指定可选参数。 就像是:

 map.connect ':lang/posts/:id', :controller => 'posts', :action => 'show', :lang => nil