mttrackback - TrackBack Technical Specification
Benjamin and Mena Trott, movabletype.org
1.1
This document describes TrackBack, a framework for peer-to-peer communication and notifications between web sites. The central idea behind TrackBack is the idea of a TrackBack ping, a request saying, essentially, ``resource A is related/linked to resource B.'' A TrackBack ``resource'' is represented by a TrackBack Ping URL, which is just a standard URI.
Using TrackBack, sites can communicate about related resources. For example, if Weblogger A wishes to notify Weblogger B that he has written something interesting/related/shocking, A sends a TrackBack ping to B. This accomplishes two things:
TrackBack uses a REST model, where requests are made through standard HTTP calls. To send a TrackBack ping, the client makes a standard HTTP request to the server, and receives a response in a simple XML format (see below for more details).
In the TrackBack system, the URL that receives TrackBack pings is
the TrackBack Ping URL. A typical TrackBack Ping URL looks like
http://www.foo.com/mt-tb.cgi/5, where 5
is the TrackBack ID.
Server implementations can use whatever format makes sense for the TrackBack
Ping URL; client implementations should not depend on a particular format.
To send a ping, the client sends an HTTP POST request to the TrackBack Ping
URL. The request contents should be of the content type
application/x-www-form-urlencoded
. For example, a ping request to the
URL http://www.foo.com/mt-tb.cgi/5 might look like this:
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_name=Foo
The possible parameters are:
...
will be added to the end.
In the Movable Type implementation, of the above parameters only url is required. If title is not provided, the value for url will be set as the title.
The response to the above query is in a simple XML format to enable
application-level error detection (HTTP-level errors will be returned as
such--for example, if the TrackBack URL points to a non-existent location on
the server, a 404
error will be returned from the ping).
A successful ping will return the following response:
<?xml version="1.0" encoding="iso-8859-1"?> <response> <error>0</error> </response>
A failed ping will return the following response:
<?xml version="1.0" encoding="iso-8859-1"?> <response> <error>1</error> <message>The error message</message> </response>
Applications should, of course, allow for the future addition of fields, if necessary. But the XML structure of the response will remain the same.
To retrieve the list of pings sent to a particular TrackBack Ping URL, send an HTTP GET request to the TrackBack Ping URL with the query string ?__mode=rss. In future revisions of the specification--once the grace period for switching to GET from POST has passed--this may be simplified such that sending a GET request to the TrackBack Ping URL will return the list of pings.
A sample GET request might look like this:
GET http://192.168.1.103/mt/mt-tb.cgi/3?__mode=rss
The response to this request will either be an error in the same format as
returned from the above request, or the list of TrackBack pings for that
item in RSS markup, wrapped in <response>
tags.
For example:
<?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>
The portions between <rss>
and </rss>
are the actual
RSS data; the rest is simply the response wrapper, and can be discarded.
TrackBack clients need a method of determining the TrackBack Ping URL for a particular URL or weblog entry. Server implementations should include embedded RDF in the pages they produce; the RDF represents metadata about an entry, allowing clients to auto-discover the TrackBack Ping URL.
Sample RDF looks like this:
<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>
Note: because current validators choke on RDF embedded in XHTML, if you want your pages to validate you may wish to enclose the above RDF in HTML comments:
<!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ... </rdf:RDF> -->
This is not a perfect solution, but it works as a temporary fix.
The dc: elements are standard Dublin Core elements; the trackback:ping element comes from the TrackBack Module for RSS 1.0/2.0 at http://madskills.com/public/xml/rss/module/trackback/.
Given a URL my_url, clients should follow these steps:
Once the client has determined the TrackBack Ping URL, it can send a TrackBack ping (see Sending a TrackBack Ping).
Example auto-discovery code is below in Examples.
To aid perspective developers in implementing TrackBack in their own systems, we are releasing a standalone implementation of TrackBack that is not dependent on Movable Type. It accepts pings sent through HTTP requests, stores the pings locally in the filesystem, and can return a list of pings sent on a particular TrackBack item in RSS format. It also generates RSS files statically, if you want it to. This can be useful for including a list of the last 15 TrackBack pings on a sidebar on your site, for example.
The standalone implementation can be downloaded from http://www.movabletype.org/downloads/tb-standalone.tar.gz.
It is released under the Artistic License. The terms of the Artistic License are described at http://www.perl.com/language/misc/Artistic.html.
Installation and usage instructions are at http://www.movabletype.org/docs/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; } } }
This Perl code defines a subroutine discover_tb. Given a URL, it attempts
to discover the TrackBack Ping URL corresponding to that URL. If it finds
it, it returns the TrackBack Ping URL; otherwise it returns undef
.
Initial release.
Thanks to Paul Prescod and others for their guidance on making TrackBack more REST-like.