Accueil > INFORMATIQUE > Systèmes de publication web > SPIP > TrackBacks sous SPIP

TrackBacks sous SPIP

lundi 12 septembre 2005, par thierrybo

SPIP offre la syndication en standard, mais ne supporte pas les TrackBacks (RétroLiens en français).

 Menu

 Introduction

Bon je l’avoue, jusqu’à il y a une semaine, je ne savais pas “exactement” ce qu’était un TrackBack, où RétroLien [1]. Je suis passé “au travers” du phénomène Blog, sans trop chercher à comprendre ce que c’était et son fonctionnement. Je voyais bien sur des sites en bas des messages des liens "Lien permanent", "Permalink", "TrackBack" ou "RétroLien", mais sans vraiment à chercher à comprendre à quoi çà servait.

Ayant basculé récemment mon site personnel sur SPIP, je parcours souvent les sites qui lui sont dédiés, et je ne sais plus quelle lecture d’un article m’a déclenché un élan de curiosité ! Je n’avais pas spécialement envie d’en mettre sur mon site personnel, çà ne changera pas grand chose, mais tant qu’à apprendre leur fonctionnement, autant les utiliser !

Après mes recherches je me suis concentré sur deux pages :

- L’article « Trackback avec SPIP » par Minh Quang, 14 mars 2004 du site Yvo*NET

- L’article de « Trackbacks pour SPIP » par James du 30 mai 2005 du site Spip.Blog et ses explications sur SPIP-Contrib.

La 1ère méthode de Minh Quang fait appel à un script externe cgi en Perl qu’il faut intégrer dans SPIP. La deuxième méthode de James est une intégration native à SPIP. "Native" n’est pas exactement le terme approprié, puisque ce n’est pas géré par défaut par SPIP. C’est simplement une “ré-écriture” en PHP adaptée et ajoutée à SPIP.

A titre personnel, la deuxième solution de James me séduit moins. Non pas qu’il y ai un problème particulier, mais je me rallie à la volonté émise par Minh Quang dans son article de toucher le moins possible au code de SPIP. J’ai déjà été "échaudé" par ce type de modifications sur le CMS Mambo, c’est pourquoi je privilégie autant que possible une solution qui ne modifie pas le code natif, ou le moins possible, rendant les mises à jour beaucoup plus simples. A ce titre, la solution de Minh Quang ne nécessite qu’une modification du squelette. Je ne vais pas expliquer la provenance du script, lisez cet article du site Cendres.net pour une explication en français, ou directement sur le site de MovableType à l’origine de TrackBack.

Allons-y pour cette solution. Je ne vais pas détailler toute les étapes, pour cela suivez l’article sur Yvo*NET, je vais simplement décrire les changements que j’y ai apporté [2] en fonction de mes besoins :

- Gestion de deux langues (il faut que #MENU_LANG soit utilisé)
- Utilisation du répertoire cgi-bin pour les scripts cgi (il faut donc pouvoir éxécuter ses propres scripts en Perl).
- Affichage des RétroLiens faits par d’autres Blogs à la suite de l’article, et non dans une fenêtre popup, reprenant ici l’implémentation de James.


Retour au Menu"

 Etape 1 : Modification du script tb.cgi pour l’adapter à mes besoins.

Mon site personnel étant bilingue, j’ai du modifier le script pour que l’affichage du texte soit dans la langue sélectionnée. Attention je n’y connais rien en Perl, les "if ...else" que j’ai utilisés ne sont peut-être pas ce qu’il y a de mieux, mais enfin çà marche.

- Faites les modifications indiquée sur le site Yvo*NET pour le fichier tb.cgi , en incluant l’étape ’facultative’ pour le formulaire administrateur.

- Ligne 10, remplacez :

my $Footer = "./footer.txt";

par :

(On va créer ce fichier après).

- Après le bloc de variables ajouté par Minh Quang, finissant par my $url = param('url');, ajoutez :

On ajoutera ce paramètre dans le squelette après.

- Ligne 39 et 40, remplacez :

   print header(), from_file($Header), <<URL;
<div class="url">TrackBack URL for this entry:

par :



- Ligne 45, insérez :



- Remplacez la ligne 49 :

<div class="footer">Tracked: %s %s</div>

par :



- Ligne 54 insérez :



- Remplacez la ligne 55 :

       my $ts = POSIX::strftime("%B %d, %Y %I:%M %p",

par :



- Ligne 65 insérez :



- Remplacez la ligne 67 :

<div align="right">[Is this your site? <a href="$me?__mode=login">Log in</a> to delete pings.]</div>

par :



- Ligne 217 insérez les lignes :



- Remplacez les lignes 221 et 222 :

Password: <input name="key" ENGINE="password" />
<input ENGINE="submit" value="Log in" />

par :

Voilà c’en est fini avec les modifications du fichier tb.cgi. Les apports ne concernent donc que le multilinguisme. Si vous n’êtes pas sûr des modifications à apporter, vous pouvez télécharger le fichier tb.cgi modifié en bas de page.


Retour au Menu"

 Etape 2 : Création du fichier footer_fr.txt

Faite une copie du fichier footer.txt en le renommant footer_fr.txt et remplacez le contenu par :


Retour au Menu"

 Etape 3 : Envoi des fichiers chez l’hébergeur

Suivez les indications du site Yvo*NET, à ces différences près :

- Il faut envoyer en plus le fichier footer_fr.txt.

- Je préfère mettre les scripts cgi dans le répertoire qui leur sont destinés, cgi-bin [3]. Les explications qui suivent correspondront donc à cette situation.


Retour au Menu"

 Etape 4 : Modification du squelette

En ce qui me concerne, je n’ajoute les RétroLiens que sur la page individuelle de chaque article, pas dans les brèves ni le sommaire. Je ne modifie que le fichier article.html du squelette.

- Ajout du compteur de trackbacks

Suivez les indications du paragraphe 3 d’Yvo*NET, mais j’ai du modifier le code d’abord pour le chemin :

  1. if (file_exists("./trackback/tb_rss/".$filetrack.".xml")) {
  2. $fichier = "./trackback/tb_rss/".$filetrack.".xml";

est remplacé par :

  1. if (file_exists("../../cgi-bin/tb_rss/".$filetrack.".xml")) {
  2. $fichier = "../../cgi-bin/tb_rss/".$filetrack.".xml";

Ensuite j’ai constaté qu’il y a un bug quand on se loggue pour supprimer les RétroLiens. Si on supprime les RétroLiens, ceux-ci sont effectivement supprimés à l’affichage mais le compteur du nombre de RétroLiens n’est pas mis à jour. En fait il ne diminue jamais, sauf si on ajoute un nouveau RétroLien. Cela est du à un bug de tb.cgi qui ne met pas à jour les fichiers XML de /cgi-bin/tb_rss/ lors des supressions. Il faut attendre qu’un nouveau RétroLien soit ajouté pour que le compteur soit à nouveau correct.
Voici comment corriger ce problème en éditant le fichier tb.cgi. Dans le bloc elsif ($mode eq 'delete'), après la ligne 82 du fichier original, ajoutez ces lignes :



- Lien vers les informations de TrackBack dans une boucle ARTICLE, Bouton vers le formulaire de ping.

Pour cette étape nous allons simplement nous inspirez du code du paragraphe 4 et 6 d’Yvo*NET, car nous voulons afficher les RétroLiens sur nos articles DANS LE CORPS de la page, et non par un lien ouvrant une fenêtre pop-up, reprenant la présentation de l’implémentation de l’article de Spip.Blog. Pour ce faire je vais utiliser une IFRAME :

Dans votre squelette, vous avez sûrement en dessous de votre article le lien "Répondre à ce message". Nous allons prendre comme base le code utilisé dans le squelette par défaut de SPIP 1.8.2 que j’utilise sur mon site (pfff, quel faignant !) :

- Remplacez la ligne :

  1. [<div class="forum-repondre"><b><a href="forum.php3?(#PARAMETRES_FORUM)"><:repondre_article:></a></b></div>]
  2. <br />

par :

  1. [(#REM) ajout lien TRACKBACK +++++++++++++++++++++++++++++++++++++++++++++++++]
  2. [<div class="forum-repondre"><b><a href="forum.php3?(#PARAMETRES_FORUM)"><:repondre_article:></a></b>
  3. | <:trackback:> :</a>
  4. <?php $num=trackbackCount("a#ID_ARTICLE"); echo ($num)?"$num":"0"; ?>]
  5. </div>
  6. <br />
  7. <?php if (isset($spip_admin)) { ?>
  8. <div class="bouton-tbping">
  9. <form method='GET' action='/cgi-bin/tb.cgi'>
  10. <input ENGINE="hidden" name="__mode" value="send_form">
  11. <input ENGINE="hidden" name="titre" value="<?echo $tb_titre; ?>">
  12. <input ENGINE="hidden" name="blog" value="<? echo $tb_blog; ?>">
  13. <input ENGINE="hidden" name="extrait" value="<? echo $tb_extrait; ?>">
  14. <input ENGINE="hidden" name="url" value="<? echo $tb_url; ?>">
  15. <input ENGINE='submit' class='spip_bouton' name='submit' value="TrackBack PING"></form>
  16. </div>
  17. <?php } ?>
  18. <script language="javascript" ENGINE="text/javascript">
  19. function iFrameHeight() {
  20. var h = 0;
  21. if ( !document.all ) {
  22. h = document.getElementById('blockrandom').contentDocument.height;
  23. document.getElementById('blockrandom').style.height = h + 60 + 'px';
  24. } else if( document.all ) {
  25. h = document.frames('blockrandom').document.body.scrollHeight;
  26. document.all.blockrandom.style.height = h + 20 + 'px';
  27. }
  28. }
  29. </script>
  30. <iframe
  31. onload="iFrameHeight()"
  32. id="blockrandom"
  33. src="/cgi-bin/tb.cgi?__mode=list&tb_id=a#ID_ARTICLE&lang=<?php echo $_GET[lang]; ?>"
  34. width="70%"
  35. height="600"
  36. scrolling="auto"
  37. align="top"
  38. frameborder="0">
  39. Cette option ne fonctionnera pas correctement car votre navigateur ne supporte pas les frames internes (iframes).
  40. </iframe>
  41. [(#REM) FIN Ajout lien TRACKBACK --------------------------------------------]

Ce code ajoute la mention "RétroLiens : xx" où xx est le nombre de rétroliens sur votre article réalisés par d’autre blogs, et les affiche en-dessous. Si en plus vous êtes administrateur, un bouton apparaît pour vous permettre de RétroLier votre article à un article d’un autre Blog.

- Informations trackback dans la boucle d’affichage du billet

Utiliser le code du paragraphe 5 d’Yvo*NET, à trois différences près, il me semble qu’il y a quelque petites erreurs dans le code proposé. :

  • J’ai essayé de comprendre la documentation de TrackBack du site MovableType et après quelques recherches sur le Net, il “semble” que les informations pour les balises RSS rdf:about et dc:identifier doivent contenir l’URL complète de l’article. En effet les outils de blog qui détectent automatiquement les RétroLiens dans les pages web doivent pouvoir lire les liens permanents (permalink) dans les blocs RSS. Tel qu’est proposé le code sur Yvo*NET, #URL_ARTICLE ne renvoie que "article.php3?id=xx" ou "nom_si_url_propre_utilisé". Si un blog effectue un RétroLien sur votre article, le lien pour y accéder sera cassé.
  • Deuxième problème, avec DotClear. A partir de DotClear, si vous créez un billet sur notre article SPIP en anglais, notre ligne dc:identifier ne contient pas la variable de langue dans l’URL. Avec DotClear, si dc:identifier est différent de l’URL réelle de la page visualisée, la détection automatique des RétroLiens échoue. Il est toujours possible de l’insérer à la main dans la fenêtre de saisie, mais c’est mieux de diminuer la saisie au maximum pour les autres rédacteurs. A noter que MovableType détecte le RétroLien automatiquement que la variable de langue soit présente ou non.

Il faut donc remplacer la balise #URL_ARTICLE pour la ligne rdf:about par :


ou :

et pour la ligne dc:identifier par :


ou :

Au lieu d’utiliser du PHP on aurait pu utiliser directement ?lang=[(#ENV{lang})], mais là encore cela pose un problème pour DotClear. Si vous visualisez un article sans jamais avoir sélectionné de langue, l’URL ne contiendra aucune variable de langue, mais ?lang=[(#ENV{lang})] forcera l’ajout de la variable de langue. L’URL étant différente de celle de dc:identifier, DotClear ne découvrira toujours pas l’url du RétroLien.
L’utilisation du filtre ?{sioui,sinon}
ne marchera pas non plus , car #ENV{lang}] contient toujours une valeur. Je n’ai pas touvé de balise SPIP permettant de récupérer un paramètre de l’URL, d’où l’utilisation de PHP.

Ensuite j’ai du remplacer :

trackback:ping="#URL_SITE_SPIP/trackback/tb.cgi/a#ID_ARTICLE"

par :

(#URL_SITE_SPIP ne peut plus être utilisé si on utilise cgi-bin.)

  • Troisième erreur que j’ai eu un peu plus de mal à cerner : J’ai essayé à partir de DotClear de créer automatiquement un trackback à partir d’une page contenant ces metadata RDF, sans succès. Ce bug n’est pas imputable à Minh Quang mais à la documentation de TrackBack Standalone. Tel que présenté, les metadata RDF sensés permettre la reconnaissance automatique des rétroliens [4] inclus dans une page ne fonctionnent pas. En effet en cherchant pourquoi DotClear ne trouvait pas le RétroLien, je me suis aperçu que le tag de fermeture de <rdf:Description> n’était pas au bon endroit.

En résumé, sur la ligne où vous aviez :

dc:identifier="[(#URL_ARTICLE|url_absolue)]?lang=[(#ENV{lang,fr})]" />
trackback:ping="http://<?php echo $_SERVER['SERVER_NAME']; ?>/cgi-bin/tb.cgi/a#ID_ARTICLE"

Vous devez avoir maintenant :

L’exemple sur la page des spécifications techniques de TrackBack est quant à lui correct.

Pour plus de clarté je remet ci-dessous le code correct (pour mon site) du bloc RDF :

- Bouton vers le formulaire de ping [5]

Le code du bouton a déjà été donné dans le paragraphe Lien vers les informations de TrackBack dans une boucle ARTICLE, qui reprend exactement le code du paragraphe 5.b. d’Yvo*NET, sauf que la cible du formulaire doit être changée de :

<form method='GET' action='#URL_SITE_SPIP/trackback/tb.cgi'>

en :

Il manque encore dans le squelette les informations permettant de remplir automatiquement les champs du formulaire d’envoi de ping. Utilisez le code du paragraphe 6.a. d’Yvo*NET, à ceci près que pour la même raison que j’indique au paragraphe Informations trackback dans la boucle d’affichage du billet, il faut indiquer les URL absolues complètes.

De plus, si on veut envoyer un ping à partir d’un article en anglais, il faut ajouter le paramètre de langue manuellement. En effet quand l’option « $forcer_lang=true » est utilisée dans « mes_options.php3 », on peut se dispenser d’ajouter le critère de langue. Toutefois cela ne fonctionne que pour les URL de type « href="#URL_ARTICLE... ». Ici nous utilisons « #URL_ARTICLE » dans une variable php.

En résumé, il faut remplacer :

$tb_url = "[(#URL_ARTICLE)]";

par :

ou :

A noter que dans notre cas où le formulaire apparait sur l’article seul, on aurait pu utiliser également :

Mais si vous voulez ajouter le formulaire sur une page où figurent plusieurs article, #SELF ne fonctionnera pas.


Retour au Menu"

 Etape 5 : Modification des fichiers de langue

Dans notre squelette article.html, nous avons utilisé deux balises de langue :

<:pister_billet:> et <:trackback:>. Ouvrez (ou créez s’ils n’existent pas) dans votre dossier /squelettes/ les fichiers local_fr.php3 et local_en.php3 et ajoutez respectivement ces chaines [6] :

et


Retour au Menu"

 Tests

Bon, c’est pas tout çà mais est-ce que çà marche !? Allons sur un article. Si vous êtes connecté en tant qu’administrateur SPIP, vous devriez voir ce bouton gris juste en dessous de vos articles :

Comme on vient d’installer TrackBack, forcément je ne peux pas vous montrer comment s’affichent les RétroLiens en dessous de l’article. Je vais donc créer un RétroLien, mais au lieu de pister un article d’un autre Blog, je vais le faire sur mon propre article, pour que vous puissiez voir quelque chose sur cette page (je l’enlèverai plus tard si jamais cet article est vraiment rétrolié par un autre blog).

Cliquez sur ce bouton, et vous devriez voir cette page, avec les informations déjà remplies :

Il n’ y a plus qu’à entrer l’URL de RétroLien que vous aurez trouvé sur l’article distant, pour cet exemple

http://www.thierryb.net/cgi-bin/tb.cgi/a33

Vous pouvez voir ce RétroLien s’afficher en dessous de cet article.

Maintenant il faut tester la création d’un vrai RétroLien à partir de mon article vers un article d’un autre Blog. Et là un doute m’assaille (comme les guerriers). Je me suis lancé à corps perdu dans la solution proposée par MovableType, mais est-ce bien compatible entre tous les blogs, qui n’utilisent pas forcément TrackBack ? Est-ce une norme ouverte ? Il faut essayer. Pour commencer, il me semble logique que je "ping" les deux articles auxquels je fais référence, chez Yvo*NET et Spip.Blog.

Voyons chez Yvo*NET. Tiens c’est étrange, il ne propose pas de RétroLiens. N’aurait-il pas implémenté sa propre méthode sur son site ? On dirait que non, tant pis.

Allons maintenant sur l’article de Spip.Blog. Il y a des RétroLiens sur cette page, et il y a le lien pour en créer un :

http://spip.blog.ouvaton.org/spip_tb.php?id_article=60

Cà tombe bien cela va me permettre de tester la compatibilité du système sur une implémentation différente des TrackBacks. A partir de cet article, on clique sur le bouton "TrackBack PING" comme je l’ai fait plus haut, mais cette fois on va mettre la vraie adresse ci-dessus du RétroLien de l’article de "James".

Essayons. Ah, l’opération semble concluante, le formulaire m’indique un succès. Toutefois en rafraichissant la page, mon article n’apparait pas à la suite des RétroLiens existants. Je vais attendre un peu. Peut-être que chaque Ping reçu dans l’implémentation de James est soumise à modération (je n’ai pas testé son système), où bien il faut attendre que le cache de sa page arrive à expiration, où bien...çà ne marche pas, mais j’espère que ce n’est pas cela !

Ah, eh bien comme on dit en anglais, Read This F... Manual ! C’est bien précisé dans son article de SPIP Contrib que les Pings sont modérés. Donc mon RétroLien n’apparaitra sur son site que s’il est accepté...

... Je complète ce chapitre après deux ou trois jours de tests. J’ai fais quelques essais entre SPIP/SPIP, SPIP/DotClear et SPIP/MovableType, dans les deux sens à chaque fois (réception/émission de pings). Tout marche bien, à l’exception des chaines de caractères transmises qui contiennent des caractères étendus (apostrophe, caractères accentués). Les échanges avec caractères étendus se passent bien avec SPIP/SPIP, SPIP/DotClear et DotClear/DotClear. Par contre avec DotClear/MovableType et SPIP/MovableType, les titres et extraits affichés sous les articles affichent par exemple “intégration” au lieu de intégration ou « d’un » au lieu de “d’un”.
Ce n’est donc pas vraiment du à l’implémentation de SPIP. C’est étonnant car paradoxalement c’est seulement MovableType, à l’origine de TrackBack, qui pose problème. La meilleure preuve est que les échanges MovableType/MovableType affichent aussi ces caractères corrompus.

Ce que j’aimerai faire maintenant c’est ajouter dans le script perl un envoi de mail automatique en cas de ping reçu. En effet les pings sont acceptés automatiquement, sans possibilité d’en avoir connaissance. Malheureusement pour l’instant je sèche ! J’arrive bien à envoyer un mail en créant un script perl vierge, mais la même chose dans le script tb.cgi le fait planter. Par exemple :

open (MAIL, "|/usr/sbin/sendmail -t ");
print MAIL <<EOM;
To: foo@domain.com
Subject: Test envoi mail

Ceci est un test d'envoi de mail.

EOM
close (MAIL);

fonctionne seul, mais ne marche pas une fois dans le script :-(

[ EDIT : L’envoi d’ émails fonctionne maintenant, la dernière version du fichier tb.cgi se trouve désormais dans l’article
Alerte Email pour TrackBack et SPIP ]

Notes :

P.-S.

P.S. : Si vous envoyez un ping sur un blog anglophone, passez l’interface en anglais avant d’envoyer le ping. Ainsi c’est le nom anglais de votre blog qui apparaitra dans le billet distant, pour peu que vous ayiez utilisé la balise <multi> dans le nom de votre site.

Notes

[1Pour ceux qui veulent savoir ce que c’est, je vous conseille de lire ces deux pages : Trackback de Wikipédia et CRAOWIKI.

[2Attention les numéros de ligne que je mentionne correspondent à chaque fois à la version non modifiée du fichier original. Au fur et à mesure de vos insertions, ces numéros vont changer.

[3Chez OVH, chaque utilisateur a son propre répertoire cgi-bin, au dessus du répertoire racine des pages web.

[4utilisée par de nombreux outils de blog

[5Fonction utilisée pour indiquer à un blogue la création d’un rétrolien. Fonction également employée pour signaler la mise à jour d’un blogue à certains sites (ex. weblogues.com).

[6ATTENTION la dernière chaine de ce fichier ne doit pas se terminer par une virgule

Répondre à cet article | RétroLiens :0


5 Messages

  • TrackBacks sous SPIP Le 12 septembre 2005 à 15:25, par James

    salut, tu as peut-être mal vu, mais il existe deux versions en php.

    - Une v1 qui ne modifie pas le noyau.
    - La v2 dont tu parles et qui en en cours de développement.

    Il est tout à fait possible et même souhaitable que cette fonctionalité soit un jour intégrée à spip. Par conséquant, il faut bien modifié le code à un moment ou un autre pour le proposer sur spip-dev un jour ;-)... et tout le monde ne peut pas forcément faire de CGI sur son hébergement.

    Par contre, les critiques sont toujours les bienvenues et il est possible de venir sur spip-zone pour faire avancer l’un ou l’autre projet.

    Enfin, James est mon véritable prénom, pas nécessaire de le mettre en guillemets :)

    Amicalement,

    Répondre à ce message

    • TrackBacks sous SPIP Le 12 septembre 2005 à 15:37, par Thierry Bothorel

      Bonjour,

      si si j’avais bien vu qu’il y a vait une V1, mais généralement les nouvelles versions ajoutent des fonctionnalités ou corrigent des bugs, rendant les anciennes obsolètes, ce qui explique que je ne m’y suis pas intérressé. Maintenant effectivement s’il s’agit simplement de deux implémentations en parallèle qui évoluent chacune de leur côté je n’avais pas compris.

      Une critique ne veut pas forcément dire "négatif". J’explique simplement que "pour mon cas" je préfère la solution qui ne modifie pas le code. Sans doute que si j’étais webmestre avec la responsabilité de un ou plusieurs sites SPIP, je m’orienterai vers votre solution qui permet de pouvoir l’adapter a ses propre besoins plus facilement.

      Thierry B.

      Répondre à ce message

      • TrackBacks sous SPIP Le 12 septembre 2005 à 16:01, par James

        Les deux implémentations sont mal nommées, faudra leur trouver d’autres noms, un jour...

        J’entends bien sur le terme « critique » dans toutes ses dimensions, pas seulement la négative :-)

        Répondre à ce message

      • TrackBacks sous SPIP Le 1er octobre 2006 à 13:06, par Franz

        Maintenant que la 1.9 est sortie, stable et fonctionnelle, un plugin est incontestablement la meilleure voie à suivre pour gérer des trackbacks.

        Répondre à ce message

        • TrackBacks sous SPIP Le 27 août 2014 à 14:53, par ceril

          I am developing an application in php language and I think this track back solution will work with my code. I am looking for a multi select method, which can enable multiple check boxes and release it in single click. Online Scams

          Répondre à ce message

Répondre à cet article