我对一个相当常见的问题略有不同:SEO友好的URL。我有一个PagesController,所以我的网址当前就像(使用restful routing):
/页/一些内容标题
这很好用,但页面有层次结构,所以我需要以下内容:
/ 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 =&gt; :controller =&gt;'pages',:id =&gt;'insurance'#但地址栏中的网址是/ insurance
/ insurance / car:controller =&gt;'pages',:category =&gt;'insurance',:id =&gt;'car'#,但地址栏中的网址是/ insurance / car
他是否有一种通用的方式让他获得他的谷歌爱情并让我保持路线健全?
谢谢!
答案 0 :(得分:5)
这很难做到,因为您根据路径中的存在(或不存在)重新定义参数。您可以处理控制器中的globbed参数,但是您没有获得所需的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 :(得分:0)
这个名为friendly_id的宝石。见its github page