I. La source XML▲
Tout d'abord, définissons la structure du forum :
<?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 :
<?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 :
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
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') );
});
});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 );
});
});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 :
<?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'><!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.
<?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.




