原文首发:Ruby中文社区
社区地址:http://www.ruby-lang.org.cn/
转载请保留版权声明并以连接形式指向原文。
最近在做一个小小的东西,使用ROR制作,在制作完成后,需要制作
Google sitemap。其实sitemap无非也就是一个xml文件而已,而在
rails里操作xml文件比切萝卜还容易,不是吗?我们有rxml模板呢。
下面来看看代码。
sitemap_controller.rb
CODE:
class SitemapController < ApplicationController
caches_action :index, :list
before_filter :set_content_type
def index
@forums = Forum.find(:all, :select => :forum_id)
end
def list
@topics = Topic.find(:all, :conditions => ['forum_id = ?', params[:id]], :select => :topic_id)
end
private
def set_content_type
@headers["Content-Type"] = "text/xml; charset=utf-8"
end
end在Controller里做的功能是相当的简单,就是将你要生成的URL的集合类取出来就行了。有几个地方需要注意:
1. caches_action :index, :list , 我们为了效率的原因,在这里使用了缓存功能,缓存了整个action.
2. @forums = Forum.find(:all, :select => :forum_id), 因为在生成URL的时候我们只会用到id这个字段,所以为了效率的原因,就只选择id字段了。
3. before_filter,这个是设置HTTP头的,本来是可以不用的,不知道为何在某些浏览器上会有问题,所以我加上了,如果你没有问题,就去掉吧。
index.rxml
CODE:
xml.instruct!
xml.sitemapindex :xmlns => 'http://www.google.com/schemas/sitemap/0.84' do
@forums.each do |f|
xml.sitemap do
xml.loc url_for(:only_path => false, :controller => 'Sitemap', :action => 'list', :id => f.id)
xml.lastmod w3c_date(Time.now)
end
end
end这里也有点要注意的地方:
1. index这个action生成的不是具体的地址,而是指向到另一些sitemap的sitemapindex.
2. url_for(:only_path) 这个可以生成完整的URL,包含了域名和端口号等。
list.rxml
CODE:
xml.instruct!
xml.urlset 'xsi:schemaLocation' => "http://www.google.com/schemas/sitemap/0.84\r[url]http://www.google.com/schemas/sitemap/0.84/sitemap.xsd[/url]", "xmlns:xsi" => 'http://www.w3.org/2001/XMLSchema-instance', "xmlns" => 'http://www.google.com/schemas/sitemap/0.84' do
@topics.each do |t|
xml.url do
xml.loc url_for(:only_path => false, :controller => 'Article', :action => 'show', :id => t.id)
xml.priority 0.9
xml.changefreq "daily"
xml.lastmod w3c_date(Time.now)
end
end
end这里就是具体的地址了,和上面的index一个道理,只是生成的xml格式不一样而已。
router.rb
CODE:
map.connect 'index.xml', :controller => 'Sitemap', :action => 'index'
map.connect ':action:id.xml', :controller => 'Sitemap', :requirements => {
:id => /\d{1,4}/,
:action => /list/
}我写这段route的目的是为了生成的URL更方便于识别,这样会生成这样的URL:
首页:http://localhost/index.xml
列表:http://localhost/list1.xml
哦,对了还有一个地方需要注意,因为我们使用了缓存,因此需要自己去检测什么时候该更新这些sitemap,我的设置是2小时就更新一次,因此需要检测是否过期,应该会有更好的办法,但是我使用了一个比较老土的办法,大家有好的招数,就提出来。
application.rb
CODE:
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
# Pick a unique cookie name to distinguish our session data from others'
before_filter :check_expire
# private
def check_expire
#expired = false
self.last_clear_time ||= Time.now
#puts self.last_clear_time
#puts Time.now
if (Time.now - self.last_clear_time) >= 2 * 60 * 60
`rake tmp:cache:clear`
self.last_clear_time = Time.now
#expired = true
end
#expired
end
def last_clear_time
name = File.expand_path("#{RAILS_ROOT}/last.update")
if File.exists? name
File.open(name, 'r') do |f|
return Time.parse(f.readline)
end
end
end
def last_clear_time=(val)
name = File.expand_path("#{RAILS_ROOT}/last.update")
File.open(name, 'w') do |f|
f.write val.to_s
end
end
end基本原理是在railsroot目录下建立一个last.update的文件,里面记录了最后一次清除的时间,然后对每个controller应用before_filter,发现超过2小时,2 * 60 * 60,会执行rake清理cache任务,当然,这样会把所有的cache全部删除,不过网站本身比较简单,也就无所谓了。
最后一点,非必需但绝非不重要,更改你的robots.txt
CODE:
sitemap: http://localhost/index.xml这样支持sitemap协议的蜘蛛就会知道你的sitemap位于这个地址之上,目前支持的有googlebot, yahooslurp, msnbot等,国内的baidu尚不支持。
OK,大功告成,去Google提交吧,你的网站马上就要流量大涨了,感谢Ruby!