mttrackback - 引用功能技術規格
Benjamin 和 Mena Trott, movabletype.org
1.1
這份文件描述了引用 (TrackBack) 功能架構,這個架構係用於網站間的點對點 (P2P) 通訊及通知。引用功能背後的中心思想,正是來自於引用通告 (TrackBack ping) 的想法。這種引用通告請求本質上所說的其實是 ``資源甲與資源乙有關/相連'' 。所謂的引用 ``資源'' 會被表示成一個引用通告網址 (TrackBack Ping URL) ,其實就是標準的 URI 。
藉由引用功能,站台間就能夠互相聯繫相關的資源。舉例來說,如果部落客甲想要讓部落客乙發現到他寫了一些東西,跟部落客乙的文章有關,或者受到其吸引/驚嚇,那麼甲就發出了一份引用通告給乙。這麼一來可以完成兩件事:
引用功能使用了 REST 模型,這裏的請求是由標準的 HTTP 叫用所產生的。要發出引用通告時,用戶端會把標準的 HTTP 請求送往伺服器,並且取回一份回應,這個回應是由簡單的 XML 格式(更多細節請見底下的敘述)寫成的。
在引用系統裏,用來接收引用通告的網址就稱做引用通告網址。典型的引用通告網址看起來就像
http://www.foo.com/mt-tb.cgi/5 ,其中的 5 又稱做引用 ID 。伺服器端的實做可以用任何合理的格式來表達引用通告網址;用戶端的實做則不該依賴任何特定的格式。
要發出通告時,用戶端會發出一份 HTTP POST 請求到引用通告網址。這份請求的內容型別應該要是
application/x-www-form-urlencoded 纔對。舉例來說,一份發往 http://www.foo.com/mt-tb.cgi/5 這個網址的通告請求,看起來就應該要像這樣:
POST http://www.foo.com/mt-tb.cgi/5 Content-Type: application/x-www-form-urlencoded title=Foo+Bar&url=http://www.bar.com/&excerpt=My+Excerpt&blog_id=Foo
可用的參數包括有:
... 。
在 Movable Type 的實做中,上述的參數裏祇有 url 是必要的。如果沒有提供 title 的話,就會把 url 的值拿來當作標題。
上述請求的回應會以簡單的 XML 格式撰寫,所以可以在應用程式層級進行錯誤偵測( HTTP 層級的錯誤也會一併被傳回 ─ 舉例來說,如果引用網址指向伺服器上不存在的位置的話,這個通告就會傳回一個 404 錯誤)。
成功的通告會傳回下列的回應:
<?xml version="1.0" encoding="iso-8859-1"?> <response> <error>0</error> </response>
失敗的通告則會傳回下列的回應:
<?xml version="1.0" encoding="iso-8859-1"?> <response> <error>1</error> <message>The error message</message> </response>
當然,應用程式應該要允許日後有需要時再增添其他欄位。不過回應的 XML 架構會保持相同。
如果要接受送到特定引用通告網址的清單,就祇需要發出一份 HTTP GET 請求到引用通告網址,並且加上 ?__mode=rss 這個查詢字串即可。在未來版本的技術規格中 ─ 當從 POST 轉換到 GET 的黃金歲月已成過往雲煙後 ─ 這個部分可能會被簡化,像是祇要送出 GET 請求到引用通告網址就會傳回通告清單之類的。
單純的 GET 請求看起來可能會像這樣:
GET http://192.168.1.103/mt/mt-tb.cgi/3?__mode=rss
這個請求的回應,可能會是從上述的請求傳回使用相同格式的錯誤,或者是用 RSS 標記成的引用通告清單,並被包在 <response> 標籤裏。
舉例來說:
<?xml version="1.0" encoding="iso-8859-1"?> <response> <error>0</error> <rss version="0.91"><channel> <title>TrackBack Test</title> <link>http://this.is/the/trackback/item/link/</link> <description>Description of the TrackBack item</description> <language>en-us</language> <item> <title>TrackBack Demo</title> <link>http://this.is/the/permalink/</link> <description>Excerpt</description> </item> </channel> </rss></response>
介於 <rss> 和 </rss> 間的部分實際上就是 RSS 資料;其他的部分就祇是被包起來的回應而已,可以丟掉不理。
引用功能用戶端需要一個方法來判斷特定網址或網誌文章項目的引用通告網址。伺服器端的實做應該要在它們所產生的頁面中嵌入 RDF ;這個 RDF 代表著該項目的詮釋資料,讓用戶端能夠自動發掘其引用通告網址。
範例 RDF 看起來像這樣:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://www.foo.com/archive.html#foo"
dc:identifier="http://www.foo.com/archive.html#foo"
dc:title="Foo Bar"
trackback:ping="http://www.foo.com/tb.cgi/5" />
</rdf:RDF>
注意:因為目前的驗證器會卡在 XHTML 裏所嵌入的 RDF ,所以如果妳想要讓妳的頁面通過驗證的話,就得把上述 RDF 包在 HTML 註解裏:
<!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ... </rdf:RDF> -->
這並非完美的解決之道,不過至少能夠暫時撐一陣子。
這裡的 dc: 元素乃是標準的都柏林核心元素 (Dublin Core elements) ;而 trackback:ping 元素則來自 RSS 1.0/2.0 的引用模組,位於 http://madskills.com/public/xml/rss/module/trackback/ 。
對於給定的網址 my_url 來說,用戶端應該要遵循下列的步驟:
當用戶端判斷出引用通告網址時,就可以發出引用通告(請參見發出引用通告)。
自動發掘功能程式碼的實例請見底下的實例。
為了協助更多開發人員將引用功能實做於她們自己的系統上,我們釋出了一份單獨實做出來的引用功能,而不再需要仰賴 Movable Type 。它會接受透過 HTTP 請求所發出的通告,並且把通告儲存於本機的檔案系統裏,也能夠用 RSS 格式傳回送往特定引用項目的通告清單。如果妳想要的話,它也能產生靜態的 RSS 檔案。舉例來說,這就能夠拿來在站台邊欄裏,列出最近接受的 15 個引用通告。
這個單獨實做出來的部分能夠從 http://www.movabletype.org/downloads/tb-standalone.tar.gz 下載。
這份工具以 Artistic License 釋出。 Artistic License 的詳細條款陳述於 http://www.perl.com/language/misc/Artistic.html 。
安裝及使用的指導則位於 tb-standalone.html 。
use LWP::UserAgent;
sub discover_tb {
my $url = shift;
my $ua = LWP::UserAgent->new;
$ua->agent('TrackBack/1.0');
$ua->parse_head(0); ## So we don't need HTML::HeadParser
$ua->timeout(15);
## 1. Send a GET request to retrieve the page contents.
my $req = HTTP::Request->new(GET => $url);
my $res = $ua->request($req);
return unless $res->is_success;
## 2. Scan te page contents for embedded RDF.
my $c = $res->content;
(my $url_no_anchor = $url) =~ s/#.*$//;
my $item;
while ($c =~ m!(<rdf:RDF.*?</rdf:RDF>)!sg) {
my $rdf = $1;
my($perm_url) = $rdf =~ m!dc:identifier="([^"]+)"!;
next unless $perm_url eq $url || $perm_url eq $url_no_anchor;
## 3. Extract the trackback:ping value from the RDF.
## We look for 'trackback:ping', but fall back to 'about'
if ($rdf =~ m!trackback:ping="([^"]+)"!) {
return $1;
} elsif ($rdf =~ m!about="([^"]+)"!) {
return $1;
}
}
}
這段 Perl 程式碼定義了一個叫 discover_tb 的副常式。對於給定的網址來說,它會試著發掘出與此網址相對應的引用通告網址。如果它找到了,就會傳回引用通告網址;否則就會傳回 undef 。
開始發行。
感謝 Paul Prescod 及其他人的指導,讓引用功能跟 REST 更為相像。