【问题标题】:Creating Friendly Rails URLs创建友好的 Rails URL
【发布时间】:2011-02-21 21:57:20
【问题描述】:

我对一个相当普遍的问题的看法略有不同:对 SEO 友好的 URL。我有一个 PagesController,所以我的 URL 目前是这样的(使用 restful 路由):

/pages/some-content-title

这很好用,但是页面有层次结构,所以我需要以下内容:

/some-content-title 路由到 /pages/some-content-title

我也可以使用:

match '*a', :to => 'errors#routing'

在我的 routes.rb 中并将其捕获在 ErrorsController 中:

class ErrorsController < ApplicationController
  def routing
    Rails.logger.debug "routing error caught looking up #{params[:a]}"
    if p = Page.find_by_slug(params[:a])
      redirect_to(:controller => 'pages', :action => 'show', :id => p)
      return
    end
    render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
  end
end

我的问题在于希望 SEO 消除 URL 的“pages/”部分。 SEO-dude 想要什么(这里有个例子很关键):

/insurance => :controller=>'pages', :id=>'insurance' # 但是地址栏的url是/insurance

/insurance/car :controller=>'pages', :category=>'insurance', :id=>'car' # 但是地址栏的url是/insurance/car

是否有一种通用的方式让他获得他对 Google 的喜爱并让我保持路线正常?

谢谢!

【问题讨论】:

    标签: ruby-on-rails routing


    【解决方案1】:

    这很难做到,因为您要根据路径中参数的存在(或不存在)重新定义参数。你可以在控制器中处理全局参数,但是你没有得到你想要的 URL,它需要重定向。

    Rails 3 允许您在创建路由时使用 Rack 应用程序作为端点。这个(遗憾的是未充分利用)特性有可能使路由变得非常灵活。例如:

    class SeoDispatcher
      AD_KEY = "action_dispatch.request.path_parameters"
    
      def self.call(env)
        seopath = env[AD_KEY][:seopath]
        if seopath
          param1, param2 = seopath.split("/") # TODO handle paths with 3+ elements
          if param2.nil?
            env[AD_KEY][:id] = param1
          else
            env[AD_KEY][:category] = param1
            env[AD_KEY][:id] = param2
          end
        end
        PagesController.action(:show).call(env)
        # TODO error handling for invalid paths
      end
    end
    #
    
    MyApp::Application.routes.draw do
      match '*seopath' => SeoDispatcher
    end
    

    将映射如下:

    GET '/insurance'     => PagesController#show, :id => 'insurance'
    GET '/insurance/car' => PagesController#show, :id => 'car', :category => 'insurance
    

    并将在浏览器中保留您的 SEO 伙计要求的 URL。

    【讨论】:

    • 太棒了,甚至不知道这个功能存在。 +1
    • 我要试试这个。看起来很有前途!谢谢。
    • 我想我错过了这个难题的一部分。你在哪里存储这个文件。我将它卡在 lib/middleware/seo_dispatcher.rb 中并在我的 application.rb 中执行了 config.middleware.use ::SeoDispatcher 但没有任何乐趣。你如何配置这个?
    • 我作弊了。我刚刚将它添加到config/routes.rb。您可以将类放在初始化程序中,或者放在lib/something.rb 中并配置环境以从那里加载它。 FWIW 这是 not 中间件,这是一个端点处理程序。请参阅中间件指南:guides.rubyonrails.org/rails_on_rack.html 和路由指南:guides.rubyonrails.org/routing.html 了解区别。端点技巧在 sec 中提到。 3.13.
    • 你有没有想过如何测试这个?甚至 cuke 也不加载 Rack。除了对代码进行单元测试之外,我有点难过。谢谢!
    【解决方案2】:

    有一个叫做friendly_id的宝石。见its github page

    【讨论】:

      猜你喜欢
      • 2011-06-27
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2011-03-03
      • 2017-11-09
      • 2015-06-02
      相关资源
      最近更新 更多