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

Cod*_*eef 22 ruby routing ruby-on-rails

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

/*lang/controller/id
Run Code Online (Sandbox Code Playgroud)

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

/en/posts/1   => lang = en
/fr/posts/1   => lang = fr
/posts/1      => lang = en
Run Code Online (Sandbox Code Playgroud)

编辑

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

map.namespace "*lang" do |lang|
  lang.resources :posts
  lang.resources :stories
end
Run Code Online (Sandbox Code Playgroud)

Cod*_*eef 19

好的,我已经设法解决了这个问题:

默认情况下,没有办法在Rails中这样做(至少,还没有).我需要安装Sven Fuchs的路由过滤器,而不是使用命名空间和默认值.

安装插件后,我将以下文件添加到我的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
Run Code Online (Sandbox Code Playgroud)

我将此行添加到routes.rb:

map.filter 'locale'
Run Code Online (Sandbox Code Playgroud)

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

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

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

这给了我以下网址和映射:

/   => :locale => 'en'
/en => :locale => 'en'
/fr => :locale => 'fr'
Run Code Online (Sandbox Code Playgroud)

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

home_path                  => /
home_path(:locale => 'en') => /
home_path(:locale => 'fr') => /fr
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的提示,这对我正在进行的一些翻译/本地化/国际化工作非常有用.仅供参考,您不必将该文件添加到库中 - 插件中已包含"语言环​​境"过滤器.您所要做的就是:1.安装插件.2.将`map.filter'locale'添加到您的routes.rb.之后它就开始工作了!尼斯.我还在我的environment.rb中添加了`RoutingFilter :: Locale.include_default_locale = false`,以避免在我的链接中出现`/ en`.效果很好,我希望Sven的插件能够进入Rails I18n代码库. (2认同)