Créez un forum animé avec XSLT et AJAX

Andrey Prikaznov

Traducteur

Didier Mouronval

Notre leçon XSLT du jour va vous montrer un résultat assez intéressant que vous pourrez utiliser. Nous allons créer un forum. Par défaut, seules les discussions seront affichées et les messages seront chargés dynamiquement (en cliquant sur la discussion) en utilisant AJAX. Vous avez peut-être déjà rencontré ce type de forum sur Internet, je vais vous montrer comment le réaliser.

Cet article a été traduit et publié avec l'aimable autorisation d'Andrey Prikaznov, l'article original (How to easily make animated forums using XSLT and Ajaxy) peut être vu sur le site Script Tutorials.

Vous pouvez déjà voir une démo en ligne ou télécharger l'archive de l'exemple.

Commentez

- Titre : Créez un forum animé avec XSLT et AJAX

- Auteur : Andrey Prikaznov

- Traducteur : Didier Mouronval

- Parution : 14 juin 2013

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2013 Andrey Prikaznov. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. La source XML

- II. Le PHP

- III. Le CSS

- IV. Le JavaScript

- V. Le XSLT

- VI. Conclusion et remerciements

I - La source XML

Tout d'abord, définissons la structure du forum :

forum.xml

<?xml version="1.0" encoding="UTF-8"?>
<forum>
<topic title="Exemple de forum XSLT" date="15.04.2011" description="Ajoutez une description ici">
<post date="15.04.2011" author="Diego">
<description><![CDATA[
Ce forum peut afficher n'importe quelle entité HTML
]]></description>
</post>
<post date="15.04.2011" author="Andrew">
<description><![CDATA[
À titre d'exemple, <b>gras</b>, <i>italique</i>, <u>souligné</u>, <a href="http://www.developpez.com">lien</a>, etc.
]]></description>
</post>
<post date="15.04.2011" author="James">
<description><![CDATA[
<p>Un paragraphe HTML <a href="http://www.developpez.com">avec un lien</a>.</p>
]]></description>
</post>
<post date="15.04.2011" author="John">
<description><![CDATA[
Bonjour le monde !
]]></description>
</post>
<post date="15.04.2011" author="Robert">
<description><![CDATA[
Un formidable forum, n'est-ce pas ?
]]></description>
</post>
</topic>
<topic title="Exemple de discussion forum 2" date="16.04.2011" description="Description de la discussion 2">
<post date="16.04.2011" author="Michael">
<description><![CDATA[
Message d'exemple 1
]]></description>
</post>
<post date="16.04.2011" author="William">
<description><![CDATA[
Message d'exemple 2
]]></description>
</post>
<post date="16.04.2011" author="David">
<description><![CDATA[
Message d'exemple 3
]]></description>
</post>
</topic>
<topic title="Exemple de discussion forum 3" date="17.04.2011" description="Description de la discussion 3">
<post date="17.04.2011" author="Charles">
<description><![CDATA[
Message d'exemple 3.1
]]></description>
</post>
<post date="17.04.2011" author="Joseph">
<description><![CDATA[
Message d'exemple 3.2
]]></description>
</post>
</topic>
</forum>

Le forum contient différentes discussions, chacune d'elles contenant un nombre variable de messages. Chaque message contient le nom de l'auteur, la date de publication et le texte lui-même (description) qui peut contenir du code HTML.

II - Le PHP

Voici le code PHP assez simple permettant d'effectuer les transformations XSL :

index.php

<?php

if (version_compare(phpversion(), "5.3.0", ">=")  == 1)
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
else
error_reporting(E_ALL & ~E_NOTICE);

// create DomDocument and load our forum
$xml = new DOMDocument;
$xml->load('forum.xml');

$xsl = new DOMDocument;

switch ($_POST['action']) {
case 'posts':
$xsl->load('xslt/posts.xslt'); // importing xslt
$proc = new XSLTProcessor; // creating xslt processor
$proc->importStyleSheet($xsl); // attaching xsl rules
$proc->setParameter('', 'topic_id', (int)$_POST['i']); // we will set param for XSL
break;
default:
$xsl->load('xslt/forum.xslt'); // importing xslt
$proc = new XSLTProcessor; // creating xslt processor
$proc->importStyleSheet($xsl); // attaching xsl rules
break;
}

echo $proc->transformToXML($xml); // output

?>

Notez bien le switch case. Pour les réponses à une requête AJAX (lorsque l'on clique sur une discussion), j'utilise le premier case (quand action vaut posts). Pour déterminer quels messages je dois afficher ((filtre), je vais passer l'identifiant de la discussion (topic_id) au script XSL.

III - Le CSS

Voici les styles utilisés :

css/styles.css

body{background:#eee;font-family:Verdana, Helvetica, Arial, sans-serif;margin:0;padding:0}
.main{background:#FFF;width:698px;min-height:500px;overflow:hidden;border:1px #000 solid;margin:3.5em auto 2em;padding:1em 2em 2em}

p{margin:0;padding:0}
.forum{border:1px solid #B0BBCD}
.forum .header{color:#fff;background-color:#545F6F;padding:5px}
.forum .topic{border-bottom:2px solid #B0BBCD;background-color:#F3F2EF;padding:5px}
.forum .topic .desc{margin-left:30px;font-size:12px;color:#444}
.forum .topic .posts{border-top:1px solid #B0BBCD;display:none;margin-top:10px;padding:10px}
.forum .topic .posts .post{border-bottom:1px solid #B0BBCD;margin:5px}
.forum .post .date{font-size:10px;color:#444;text-align:right}

Il contient les styles du forum, des discussions, des messages, etc.

IV - Le JavaScript

Le dossier js/ contient le fichier jQuery (js/jquery.min.js) et

js/main.js

function loadPosts(obj, i) {
$('.topic#'+i+' .posts').load('index.php',
{action: 'posts', i: i},
function() {
$(this).fadeIn('slow');

obj.unbind('click');
obj.click(function(e) {
$('.topic#'+i+' .posts').slideToggle('slow');
});
}
);
}

$(function(){
$('.topic').click(function() {
loadPosts( $(this), $(this).attr('id') );
});
});

Note du traducteur : le code JavaScript proposé repose sur la version 1.3.2 de jQuery qui est ancienne (l'article original date d'avril 2011).
Un code correspondant à une version plus récente de jQuery pourrait être :

function loadPosts(obj, i) {
$('.posts', obj).load('index.php',
{action: 'posts', i: i},
function() {
$(this).fadeIn('slow');

obj.on('click', function() {
$('.posts', this).slideToggle('slow');
});
}
);
}

$(function(){
$('.topic').one('click', function() {
loadPosts( $(this), this.id );
});
});

Notez en particulier l'utilisation des méthodes .on() et .off() pour gérer les événements ainsi que l'utilisation de .one() pour déclarer un événement à n'exécuter qu'une fois.
Ce code a été testé avec les versions 1.10.1 et 2.0.2 de jQuery.

Lorsque le DOM est chargé, j'affecte un événement clic aux discussions du forum. Ensuite, lorsque l'on clique sur une discussion, j'utilise $.load() pour charger les messages de cette discussion. J'en profite pour désactiver l'événement clic existant et je le remplace par une fonction qui va alterner l'affichage et le masquage des messages.

V - Le XSLT

Enfin, la délicatesse des règles XSLT :

xslt/forum.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<xsl:text disable-output-escaping='yes'>&lt;!DOCTYPE html></xsl:text>
<html>
<head>
<script src="js/jquery.min.js"></script>
<script src="js/main.js"></script>
<link media="all" href="css/styles.css" rel="stylesheet"/>
<title>Notre forum AJAX / XSLT</title>
</head>
<body>
<div class="main">
<h2>Notre forum AJAX / XSLT</h2>
<div class="forum">
<div class="header">Discussions du Forum</div>
<xsl:for-each select="forum/topic">
<div class="topic">
<xsl:attribute name="id">
<xsl:value-of select="position()"/>
</xsl:attribute>

<a class="top_link" href="javascript:void(0)">
<xsl:value-of select="@title"/> (<xsl:value-of select="count(child::*)"/>)
</a>
<div class="desc">
<xsl:value-of select="@description"/>
</div>
<div class="posts"></div>
</div>
</xsl:for-each>

</div>
</div>
<xsl:comment>Copyright : AndrewP</xsl:comment>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Note du traducteur : le code proposé ici est légèrement différent de celui de l'auteur (et de celui de l'archive de l'exemple). Il a été traduit et le doctype utilisé pour le rendu HTML a été modifié. Notez à ce sujet l'astuce utilisée pour obtenir un doctype HTML5, seule façon de procéder actuellement à ma connaissance.

Comme vous pouvez le constater, nous générons ici uniquement la partie principale du forum avec uniquement les discussions. Nous chargerons les messages avec AJAX pour chaque discussion à l'aide de jQuery.

xslt/posts.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="forum/topic[position() = $topic_id]/*">
<div class="post">
<xsl:attribute name="id">
<xsl:value-of select="position()"/>
</xsl:attribute>
<xsl:value-of select="description" disable-output-escaping="yes"/>
<div class="date">
posté à <xsl:value-of select="@date"/> par <xsl:value-of select="@author"/>
</div>
</div>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Pour ce fichier, seule la traduction du texte a été effectuée.

Le second fichier XSL va servir à générer les messages pour la discussion demandée. J'espère que vous n'avez pas oublié que les messages sont récupérés avec AJAX. Nous avons passé la variable $topic_id depuis le fichier PHP (voir index.php). Nous n'affichons donc que les messages correspondant à la discussion souhaitée.

VI - Conclusion et remerciements

Vous pouvez voir une démo en ligne ou télécharger l'archive de l'exemple.

J'espère que l'exemple d'aujourd'hui vous a plu et que votre intérêt pour XSLT n'a pas diminué !

Cet article a été traduit et publié avec l'aimable autorisation d'Andrey Prikaznov, l'article original (How to easily make animated forums using XSLT and Ajaxy) peut être vu sur le site Script Tutorials.

Nous tenons à remercier ClaudeLELOUP pour sa relecture attentive de cet article.