Ostatnio napisałem jak można odebrać i wysłać pingback, teraz pora na coś starszego – Trackback (specyfikacja). Został on wymyślony na początku XXI wieku przez firmę SixApart i zaimplementowany w MovableType. Z tego co się orientuje, to na pewno nie był on wspierany przez Bloggera – teraz nie wiem jak jest.
Ogólnie ja rozumiem to tak – Pingback coś nowego, Trackback – coś starego. Jednak wciąż niektóre serwisy wysyłają trackbacks i nie posiadają implementacji pingback. Jeżeli chcemy śledzić kto do nas linkuje, to najlepiej jest zaimplementować obydwa linkbacki.
Implementacja
Z Trackback jest dużo prościej niż z pingback, ze względu na to, iż wykorzystuje on model REST i odbieranie następuje poprzez HTTP POST/PUT (warto zaimplementować to i to). Dzięki czemu nie musimy tworzyć żadnych serwisów itp., wystarczy akcja w MVC lub odpowiednie WebAPI.
Plusem trackbacka jest to, że możemy mieć ID naszego postu, przez co nie trzeba się męczyć z weryfikacją po urlu, ale o tym napiszę w sekcji wykrywania.
Samo odebranie trackback jest proste:
// http://www.sixapart.com/labs/trackback/
// http://www.movabletype.org/documentation/trackback_manual.html
[AcceptVerbs("POST", "PUT")]
public ActionResult Trackback(string blog_name,
string url,
string title,
string excerpt,
int id)
{
var model = new TrackbackInput
{
blog_name = blog_name,
url = url,
title = title,
excerpt = excerpt
};
if (model.url.IsNullOrWhiteSpace())
{
return TrackbackError("URL Is Missing");
}
var post = GetPostById()(id);
// checks if post exists
if (post == null)
{
return RedirectToAction("AllPosts", "Posts");
}
var postUrl = Url.Action("Details", "PostDetails", post.ToRouteData());
// same as with pingback, checks if url exists on target site
if (postUrl.ExistsOn(model.url) == false)
{
return TrackbackError("The source page does not link");
}
var comments = GetComments(post.CommentsId);
if (comments.AreCommentsClosed()|| post.AllowComments == false)
{
return TrackbackError("Comments closed");
}
var trackbackExists = comments.UrlExists(model.url);
if (trackbackExists)
{
return TrackbackError("Trackback already registered");
}
var comment = new PostComments.Comment();
comment.IsSpam = _akismetService.CheckForSpam(comment);
if (comment.IsSpam)
{
// do something with spam
}
else
{
// do something with not spam
// like add to comments
}
return TrackbackSuccess();
}
Wykorzystuje tutaj dwie pomocnicze metody zwracające wynik w postaci XML – success zawiera element error i wartość zero, zaś error, element error i wartość tekstową (warto o tym pamiętać przy wysyłaniu):
private ActionResult TrackbackError(string error)
{
var response = new XDocument(
new XElement("response",
new XElement("error", error)
)
);
return XDoc(response);
}
private ActionResult TrackbackSuccess()
{
var response = new XDocument(
new XElement("response",
new XElement("error", "0")
)
);
return XDoc(response);
}
ps. XDoc to metoda pomocnicza zwracająca XML z XDocument.
Autowykrywanie
By zewnętrzne serwisy wiedziały o tym, że nasz blog odbiera trackbacki, do każdego postu/strony dla której chcemy zezwolić dodawanie trackback, musimy wygenerować mniej więcej taki o to kod HTML:
<!-- this needs to be a comment block -->
<!-- dc: http://dublincore.org/documents/dces/ -->
<!--
<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="LINK_TO_POST"
dc:identifier="UNIQUE_LINK_TO_POST"
dc:title="POST_TITLE"
trackback:ping="OUR_TRACKBACK_URL_WITH_POST_ID" />
</rdf:RDF>
-->
Można to wykonać na przykład za pomocą extension method:
public static class HtmlExtensions
{
public static MvcHtmlString TrackbackRdf(this HtmlHelper html, PostViewModel post)
{
if (post.AreCommentsClosed || post.Post.IsCommentAllowed == false)
{
return MvcHtmlString.Create(string.Empty);
}
var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
var postUrl = urlHelper.AbsoluteAction("Details", "PostDetails", post.Post.ToRouteData());
var trackbackUrl = urlHelper.AbsoluteAction("Trackback", "Services", new
{
id = post.Post.Id
});
return MvcHtmlString.Create(GetTrackbackRdf(postUrl, post.Post.Title, trackbackUrl));
}
// i think I did downloaded this code from somewhere...
private static string GetTrackbackRdf(string postUrl, MvcHtmlString postTitle, string trackbackUrl)
{
var sb = new StringBuilder();
sb.AppendLine(@"<!--");
sb.AppendLine(@"<rdf:RDF xmlns:rdf=""http://www.w3.org/1999/02/22-rdf-syntax-ns#"" ");
sb.AppendLine(@"xmlns:dc=""http://purl.org/dc/elements/1.1/"" ");
sb.AppendLine(@"xmlns:trackback=""http://madskills.com/public/xml/rss/module/trackback/"">");
sb.AppendLine(@"<rdf:Description ");
sb.AppendLine(@"rdf:about=""{0}"" ".FormatWith(postUrl));
sb.AppendLine(@"dc:identifier=""{0}"" ".FormatWith(postUrl));
sb.AppendLine(@"dc:title=""{0}"" ".FormatWith(postTitle));
sb.AppendLine(@"trackback:ping=""{0}"" />".FormatWith(trackbackUrl));
sb.AppendLine(@"</rdf:RDF>");
sb.AppendLine("-->");
return sb.ToString();
}
}
Podsumowanie
Implementacja jest dużo prostsza niż przy pingback, jednak wymaga ekstra kodu na stronie, niektórzy tego nie lubią. W WordPress na przykład przez powinien czas usunęli w ogóle metodę która umożliwiała generowanie rdf – ale potem szybko ją przywrócili ;) ale zostałam poruszona pewna kwestia na którą też warto zwrócić uwagę – niektóre blogi, mogą udostępniać trackback, ale poprzez element link rel=trackback.
To tyle, następnym razem napiszę jak można taki trackback wysłać.
A wy korzystanie z trackbacków czy z pingabacków? Czy wam to wszystko jedno? ;)















A czemu akcja nie przyjmuje bezpośrednio TrackbackInput ?
Mi wszystko jedno czy trackback czy pingback bo mimo lektury wszystkich twoich postów na ten temat nadal nie wiem czym się różnią i… don’t care;)
Z TrackbackInput wiaze sie historia… w testach integracyjnych po prostu nie dzialal. Jest to zapewne wina model bindera, ale zamiast meczyc sie nim pozostawilem to tak jak jest teraz.
na przyklad taki o to kod:
var client = new RestClient(“http://localhost:8848/”);
var request = new RestRequest(“trackback/1569”, Method.POST);
request.AddParameter(“blog_name”, “some_value”);
request.AddParameter(“url”, “some_value”);
request.AddParameter(“title”, “some_value”);
request.AddParameter(“excerpt”, “some_value”);
powodowal, ze model mial wszystkie wartosci null, a w ten sposob jest wysylany trackback.
Zas co do roznicy… jak dalej nie wiesz to znaczy ze dobrze. Roznicy pomiedzy trackback a pingback nie ma – jest roznica pomiedzy protokolami ale to wszystko. Jak sie czlowiek wysili to mozna zaobserwowac dwie male roznice (jezeli je roznicami mozna nazwac) jakie ja widze to: Trackback musi miec url, a pingback jest autowykrywalny za pomoca header.
oraz trackback jest bardziej podatny na spam ze wzgledu na parametry typu `excerpt`
Comments are closed.