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:
698
px;
min-height:
500
px;
overflow:
hidden
;
border:
1
px #000
solid
;
margin:
3.5
em auto
2
em;
padding:
1
em 2
em 2
em}
p{
margin:
0
;
padding:
0
}
.forum
{
border:
1
px solid
#B0BBCD
}
.forum
.header
{
color:
#fff
;
background-color:
#545F6F
;
padding:
5
px}
.forum
.topic
{
border-bottom:
2
px solid
#B0BBCD
;
background-color:
#F3F2EF
;
padding:
5
px}
.forum
.topic
.desc
{
margin-left:
30
px;
font-size:
12
px;
color:
#444
}
.forum
.topic
.posts
{
border-top:
1
px solid
#B0BBCD
;
display:
none
;
margin-top:
10
px;
padding:
10
px}
.forum
.topic
.posts
.post
{
border-bottom:
1
px solid
#B0BBCD
;
margin:
5
px}
.forum
.post
.date
{
font-size:
10
px;
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.