iT邦幫忙

DAY 18
9

Rails 的簡單任務系列 第 19

[RoR] 透過 permalink 使網址具可讀性

第3日 為例,常常網路上看到的網址是 http://SITE/blog/show/prison-break ,而不是 http://SITE/blog/show/2 ,使網址更具可讀性及意義;若不希望每篇文章或 user 的資料被 1..∞ 的順序被瀏覽的話,這是可以用 permalink 的方式來實現。
可參考 http://punk.tw/2007/10/06/340.html 的概念與作法,該文章中是以標題+時間進行md5的編碼做為 permalink ,是以保護不被以序號、流水號的方式被 try 出所有的資料出來,所以做出的 permalink ,人眼去讀是沒有意義的字碼;如果文章本來就是希望被讀、被 index 的話,其實是要讓網址具有可讀性,除非是像提供檔案下載的網址,不想通通全部被人都抓走,才不需要有可讀性及辨識性,才以編碼方式為名稱。而本文是要以可讀性為目標來設定:
新增 permalink 欄位

./script/generate migration AddPermalinkToArticle
# vi db/migrate/2008xxxxxxx_add_permalink_to_article.rb 修改成以下內容
class AddPermalinkToArticle < ActiveRecord::Migration
  def self.up
   add_column :articles, :permalink, :string
   add_index :articles, :permalink
  end
  def self.down
   remove_index :articles, :permalink
   remove_column :articles, :permalink
  end
end
# 再執行
rake db:migrate

測試 permalink 的語法
參考怎麼從文章的標題來做出 perlmalink 的語法 Permalink from post title ,透過以下指令來試驗一下:

./script/console
Loading development environment (Rails 2.1.1)
>> t = 'Prison Break'
=> "Prison Break"
>> t.downcase.gsub(/[^a-z0-9]+/,'-').to(127).gsub(/^-+|-+$/,'')
=> "prison-break"

上述的語法基本是,字串變小寫,不是字母及數字的字串,改為'-'符號連結,整個字串最長到127個字元,若是以'-'為最開始或結束,則砍掉最前最末的'-'符號。所以就可以簡化成這樣的語法來使用。

為現有的文章補 permalink 的值
可透過 ./script/console 來測試及直接將 permalink 的值補進去:

# 先測試一下語法是否可成功
>> Article.find(:all).each {|a| puts a.title.downcase.gsub(/[^a-z0-9]+/,'-').to(127).gsub(/^-+|-+$/,'') }
save-the-cheerleader-save-the-world
prison-break
..
=> [#<Article id: 1, title: "Save the Cheerleader, Save the World", body: ...
...
# 用這樣的語法就可以把現有文章的所有 permalink 重新補上
>> Article.find(:all).each {|a| a.permalink = a.title.downcase.gsub(/[^a-z0-9]+/,'-').to(127).gsub(/^-+|-+$/,''); a.save }

這樣原有的文章,原來 permalink 是空值的話,就都補上了。

網址唯一性的問題
但還要考慮的是,若不同的文章卻有同樣的標題,那不就會造成重覆的網址嗎?可參考 Model Name in URL 的作法,讓網址的參數是 id + permalink ,就不會有重覆的網址。

讓新增的文章自動加入 permalink

# 編輯 app/models/article.rb
class Article < ActiveRecord::Base
before_save :generate_permalink

def to_param
  "#{id}-#{permalink}"
end

protected
 def generate_permalink
  self.permalink = self.title.downcase.gsub(/[^a-z0-9]+/,'-').to(127).gsub(/^-+|-+$/,'')
 end
end

# 在 app/views/blog/index.html.erb 中的各文章連結改為 
<%= link_to article.title, :action => 'show', :id => article -%>

這樣網址就會變成:http://SITE/blog/show/2-prison-break 即可連到各別文章,且是具有可讀性的網址了。然而用 http://SITE/blog/show/2 也還是看得到該文;就文章而言,是還好,但若是 user 的 profile 檔,就真的不希望這樣子就都被讀取到,所以若是 user 的 profile 的 show,就會以 find_by_username ,只能以 username 來查詢,而無法用 id 來查詢了。

但是在中文世界,大部份文章不都是以中文為標題?此法就不是那麼適用嗎?明天就來探索以中文來做 permalink 的方法。


上一篇
[RoR] 利用 before_filter 的簡單存取控制
下一篇
[RoR] 中文轉漢語拼音的 permalink
系列文
Rails 的簡單任務33

1 則留言

0
gric
iT邦高手 1 級 ‧ 2009-03-14 13:09:51

感恩分享咯!

我要留言

立即登入留言