respond_to 新构想
respond_to 非常好用,可以根据不同的 format 来选择不同的应答策略,并且自动设置相应的 MIME 值,看上去也非常爽目。
在 Blog 系统中,比如文章的 RSS,就可以:
-
def index
-
@posts = Post.find(:all)
-
respond_to do |format|
-
format.html { ...}
-
format.rss {...}
-
end
-
end
这样比在单独构建一个 RSS action 要好得多~
不过,如果 Blog 通过 html 显示出来的话,还需要做其他一些事情,比如构建 Blog 的各个边栏,这些事情一般都放在 before_filter 中去做:
-
class PostsController < ApplicationController
-
before_filter :get_sidebars
-
...
但是这些工作在 RSS 中完全不需要,那么怎么在 RSS 忽略掉这些工作呢?
一个选择就是去掉 before_filter,把 get_sidebars 写入到 format.html { } 中去,这样的话,PostsController 里面每个 action 的 format.html 都要这样做,不是啥好办法。
第二个选择就是在 get_sidebars 里面检测 format:
-
def get_sidebars
-
if params[:format] == "html"
-
...create sidebars
这样似乎还算 ok,其他的方法还没有想出来……
前两天,正好看到 maiha 写的新 respond_to 表示方法的构想,去掉 respond_to 那个 block,而按照 aciton.format 的格式,把不同 format 的处理,放到单独的函数中去:
-
def index
-
@posts = Post.find(:all)
-
end
-
-
def index.html
-
...
-
end
-
-
def index.rss
-
...
-
end
这样看上去比 respond_to 清晰了很多,如果可以实现,那么如果在 before_filter 里面也可以:
-
before_filter :get_sidebars, :only => "*.html"
就能完美的解决上面的问题了~
rake rails:update
今天才发现有这个 rake 任务……
rake rails:update 自动帮你升级项目中的配置文件、脚本、还有默认的 javascript 文件,如果你的项目是在旧版的 rails 之上构建的,只要一个命令,就跟在新版上构建的无异啦~ 原来我还傻乎乎的建个空项目然后把新的文件拷过来……
你还可以升级更详细的部分:
(in /root/work/chito)
rake rails:update
Update both configs, scripts and public/javascripts from Rails
rake rails:update:configs
Update config/boot.rb from your current rails install
rake rails:update:javascripts
Update your javascripts from your current rails install
rake rails:update:scripts
Add new scripts to the application script/ directory
不过因为用了新版 prototype 和 scriptaculus 的缘故,新版 rails 的默认 javascript 比旧版的尺寸大了很多,如果旧版用的好好的,就不用升级了,比如我……
中文相对时间
不知道啥时候开始,流行用相对时间来表示当前的日期,这种方法确实是不错,同 “2007 年 1 月 24 日” 相比,“1 天前” 这种表示确实看起来舒服多了,毕竟人们在思考时间的时候,大多数也是以当前的时间作为基点。
如果是个是个人气很旺的论坛之类,还可以看到某回复发表于 “n 分钟前” 这样的效果,顿时感觉人气和交互度高了很多。
Rails已经内置了对相对时间的支持,time_ago_in_words 这个 helper 就是干这个用的,比如要显示文章发表的相对时间:
这样就会显示为诸如 “post at 5 days ago” 这样的效果了~
只不过是英文的,要显示中文的就要翻译一下了,开始我想,把 time_ago_in_words 返回结果中的 days 替换成“天”、month 替换成“月”之类,后来去看了下源码,发现源码很短,重新写一个就行了。
time_ago_in_words 实际上是调用的 distance_of_time_in_words 这个函数,并且以 Time.now 作为第二个参数而已:
distance_of_time_in_words(from_time, Time.now, include_seconds)
end
这样的话,我们把 distance_of_time_in_words 中的英文改成中文就 ok 了:
-
def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
-
from_time = from_time.to_time if from_time.respond_to?(:to_time)
-
to_time = to_time.to_time if to_time.respond_to?(:to_time)
-
distance_in_minutes = (((to_time - from_time).abs)/60).round
-
distance_in_seconds = ((to_time - from_time).abs).round
-
-
case distance_in_minutes
-
when 0..1
-
return (distance_in_minutes == 0) ? '不到 1 分钟' : '1 分钟' unless include_seconds
-
case distance_in_seconds
-
when 0..4 then '不到 5 秒'
-
when 5..9 then '不到 10 秒'
-
when 10..19 then '不到 20 秒'
-
when 20..39 then '半分钟'
-
when 40..59 then '不到 1 分钟'
-
else '1 分钟'
-
end
-
-
when 2..44 then "#{distance_in_minutes} 分钟"
-
when 45..89 then '大约 1 小时'
-
when 90..1439 then "大约 #{(distance_in_minutes.to_f / 60.0).round} 小时"
-
when 1440..2879 then '1 天'
-
when 2880..43199 then "#{(distance_in_minutes / 1440).round} 天"
-
when 43200..86399 then '大约 1 个月'
-
when 86400..525599 then "#{(distance_in_minutes / 43200).round} 个月"
-
when 525600..1051199 then '大约 1 年'
-
else "#{(distance_in_minutes / 525600).round} 年"
-
end
-
end
把上面的代码加到 application_helper.rb 中去,就可以看到中文的相对时间了~ 当然你也可以去掉 “大约” 这个繁琐的词,或者随便改成自己喜欢的中文表达方式~
过两天就做 Chito 的相对时间插件~
用rails实现简单的网页伪静态化
只需要修改几个字符,就可以让rails生成.html后缀的url,实现基于rails的简单的网页伪静态化。