Tutorial : les boucles forums

Nous allons faire ici le tour de ce qu’il faut savoir pour bien manipuler la boucle forum.

Ce tutorial est une application de la boucle forum décrite ici dans la documentation de Spip

Préalable

Créez une nouvelle rubrique et dedans un nouvel article, notez le numéro de la rubrique et créez un fichier vide que vous nommez article-XX.html ou XX est le numéro de la rubrique.

Le tutorial suivant va vous permettre de voir comment gérer les différents affichages utiles pour des forums étape par étape.

Les types de messages

On distingue deux types de messages :

-  Les sujets

Les sujets sont les messages de niveau 1, c’est à dire que l’on créer un sujet en répondant à un article (ou une brève, ou encore une rubrique).

-  Les réponses

Les réponses sont des messages de niveau 2 ou plus, une réponse est postée en répondant à un sujet ou à une réponse.

Répondre à un article

Pour répondre à un article il faut ajouter l’appel que voici

[<p><a href="forum.php3?(#PARAMETRES_FORUM)"> Nouveau sujet </a></p>]

Ce code appelle par défaut la page forum.php3/html de Spip qui permet de rédiger un message, il faut impérativement le mettre dans le corps de la boucle article pour permettre à Spip de calculer correctement la valeur de #PARAMETRES_FORUM.

Afficher tous les Sujets

Voici une boucle qui permet de créer un sujet en réponse à un article, d’afficher les sujets et d’en compter le nombre. Recopiez la dans votre fichier article-XX.html et créez un certain nombre de sujets.

<BOUCLE_principale(ARTICLES){id_article}>

[<p><a href="forum.php3?(#PARAMETRES_FORUM)"> Nouveau sujet </a></p>]


<B_sujets>
<ul>
<BOUCLE_sujets(FORUMS){id_article}{par date}{inverse}>

<li>#TITRE</li>

</BOUCLE_sujets>
</ul>
Il y a #TOTAL_BOUCLE sujets postés en réponse à cet article
</B_sujets>


</BOUCLE_principale>

Afficher les 5 derniers sujets et leurs réponses directes

Voici maintenant comment lister les 5 derniers sujets, permettre d’y répondre et afficher les réponses directes à ces sujets (on comptera les réponses pour la forme)

<BOUCLE_principale(ARTICLES){id_article}>

[<p><a href="forum.php3?(#PARAMETRES_FORUM)"> Nouveau sujet </a></p>]

<B_sujets>
<ul>
<BOUCLE_sujets(FORUMS){id_article}{par date}{inverse}{0,5}>

<li>#TITRE[ <a href="forum.php3?(#PARAMETRES_FORUM)"> répondre</a>]</li> 

<B_reponses>
<ul>
<BOUCLE_reponses(FORUMS){id_parent}{par date}>
<li>#TITRE</li>
</BOUCLE_reponses>
</ul>
Il y a #TOTAL_BOUCLE réponses postées en réponse à cette réponse.
</B_reponses>


</BOUCLE_sujets>
</ul>

</BOUCLE_principale>

Permettre de répondre aux réponses et voir ces réponses

Chaque message, quelque soit son niveau dans la hiérarchie des réponses, est considéré comme un élément de type (FORUMS), cela permet à Spip gérer les réponses aux réponses indéfiniment.

On accède aux réponses du niveau d’en dessous en utilisant le critère {id_parent} dans une boucle (FORUMS) contenue dans la boucle (FORUMS) du niveau supérieur.

Fort bien, mais comme on ne peut pas savoir par avance combien de niveaux de réponses va engendrer un sujet, il est impossible de prévoir le nombre de boucles de forum imbriquées nécéssaires, on utilisera donc une astuce qui va nous permettre de prendre en compte tous les cas de figure d’un coup : une boucle récursive.

Voici donc la même boucle que précédement, mais qui permet en plus de répondre aux réponses indéfiniment.

<BOUCLE_principale(ARTICLES){id_article}>

[<p><a href="forum.php3?(#PARAMETRES_FORUM)"> Nouveau sujet </a></p>]

<B_sujets>
<ul>
<BOUCLE_sujets(FORUMS){id_article}{par date}{inverse}{0,5}>

<li>#TITRE[ <a href="forum.php3?(#PARAMETRES_FORUM)"> répondre</a>]</li>

<B_reponses>
<ul>
<BOUCLE_reponses(FORUMS){id_parent}{par date}>
<li>#TITRE[ <a href="forum.php3?(#PARAMETRES_FORUM)"> répondre </a>]</li>
<BOUCLE_recursive(boucle_reponses)></BOUCLE_recursive>
</BOUCLE_reponses>
</ul>
Il y a #TOTAL_BOUCLE réponses postées en réponse à cette réponse.
</B_reponses>


</BOUCLE_sujets>
</ul>

</BOUCLE_principale>

Compter les messages

Il peut etre intérressant pour une page d’accueil de formum de savoir le nombre de sujets et de contributions totales à un article.

-  Compter les sujets

Si vous êtes observateur vous avez remarqué que l’on compte les sujets comme ca :

<BOUCLE_compte_sujets(FORUMS){id_article}> </BOUCLE_compte_sujets>
<p>#PUCE Il y a #TOTAL_BOUCLE sujets en réponse à cet article</p>
</B_compte_sujets>

On ne met qu’un espace au milieu de la boucle car ce qui nous intérresse c’est juste qu’elle tourne pour qu’on puisse compter le nombre de tour.

Vous voyez qu’avec le critère {id_article} Spip compte par défaut le nombre de réponses directement lié à l’article (donc Spip compte les sujets). Si on veut prendre en compte les réponses et les réponses de niveaux inférieurs (les réponses au sujet et les réponses à ces réponses), il faut ajouter le critère {plat} ca donne :

-  Compter tous les messages

<BOUCLE_compte_messages(FORUMS){id_article}{plat}> </BOUCLE_compte_messages>
<p>#PUCE Il y au total #TOTAL_BOUCLE messages en réponse à cet article</p>
</B_compte_messages>

En intégrant tout ça notre fichier article-XX devient :

<BOUCLE_principale(ARTICLES){id_article}>


<BOUCLE_compte_sujets(FORUMS){id_article}> </BOUCLE_compte_sujets>
<p>#PUCE Il y a #TOTAL_BOUCLE sujets en réponse à cet article</p>
</B_compte_sujets>


<BOUCLE_compte_messages(FORUMS){id_article}{plat}> </BOUCLE_compte_messages>
<p>#PUCE Il y au total #TOTAL_BOUCLE messages en réponse à cet article</p>
</B_compte_messages>

<hr>

[<p><a href="forum.php3?(#PARAMETRES_FORUM)"> Nouveau sujet </a></p>]

<B_sujets>
<ul>
  <BOUCLE_sujets(FORUMS){id_article}{par date}{inverse}{0,5}>
  <li>#TITRE[ <a href="forum.php3?(#PARAMETRES_FORUM)"> Nouvelle réponse </a>]</li>
  <B_reponses>
  <ul>
    <BOUCLE_reponses(FORUMS){id_parent}{par date}>
    <li>#TITRE[ <a href="forum.php3?(#PARAMETRES_FORUM)"> Nouvelle réponse </a>]</li>
    <BOUCLE_recursive(boucle_reponses)>
    </BOUCLE_recursive>
    </BOUCLE_reponses>
  </ul>
  Il y a #TOTAL_BOUCLE réponses postées en réponse à cette r&eacute;ponse. 
  </B_reponses>
  </BOUCLE_sujets>
</ul>

</BOUCLE_principale>

Lister les sujets par date inverse des réponses

Âmes sensibles s’abstenir...

Jusqu’ici on listait les sujets du plus récent au plus ancien, mais bien souvent ce qui nous interesse quand on liste les sujets c’est de faire “remonter” un sujet en haut de la pile lorsqu’il recoit une nouvelle réponse. Il faut donc trier les sujets par rapport à la date de leur dernière réponse. Vous êtes bien accrochés ???

-  Récupérer le sujet à l’origine de la discussion où le dernier message a été posté

Pour cela il va falloir utiliser le critère {id_enfant} qui permet de remonter d’un cran. On peut donc savoir de quel message le message courant est la réponse. Mais pour retrouver le sujet il va falloir remonter jusqu’en haut, c’est à dire jusqu’a ce que le message courant n’ai plus de message père car le sujet c’est précisement le message qui n’a pas de père.

L’idée est donc de remonter la hierarchie depuis le dernier message grâce à une boucle récursive et quand on ne trouve plus de résultat (ce qui veut dire qu’on est arrivé en haut) on affiche (donc en code alternatif) le titre du message : qui sera le sujet.

<BOUCLE_liste(FORUMS){id_article}{plat}{par date}{inverse}{0,1}> 

<BOUCLE_remonte(FORUMS){id_enfant}>
<BOUCLE_remonte_rec(boucle_remonte)> </BOUCLE_remonte_rec>
</BOUCLE_remonte>
<br>#TITRE
<//B_remonte>

</BOUCLE_liste>
<hr>
</B_liste>

Bon maintenant qu’on a réussit à récupérer le sujet du dernier message on va pouvoir continuer avec les autres messages les plus récents, mais on risque d’avoir un problème si les messages proviennent d’un sujet déjà listé en effet il ne faudrait pas re lister même le sujet.

En général dans Spip il suffit de mettre le critère {doublons} pour s’assurer que Spip ne re affiche pas un élément déjà affiché par une autre boucle, mais malheureusement ca ne marche pas à l’intérieur d’une même boucle.

Donc pas la peine de tenter de lister les messages issus du sujet qu’on vient de trouver dans une boucle imbriquée avec un {doublons} et de mettre un {doublons} à la boucle liste, ca ne marchera pas parce qu’on reste dans la boucle liste. Du coup on va utiliser un tableau php et vérifier que le sujet n’est pas déjà dedans avant de l’afficher.

<?php $tableau = array();?>
<BOUCLE_liste(FORUMS){id_article}{plat}{par date}{inverse}> 

<BOUCLE_remonte(FORUMS){id_enfant}>
<BOUCLE_remonte_rec(boucle_remonte)> </BOUCLE_remonte_rec>
</BOUCLE_remonte>
<?php 

$id_forum='[(#ID_FORUM|texte_script)]';
$titre='[(#TITRE|texte_script)]';
if(!in_array($id_forum,$tableau)) echo $titre."<br>";
$tableau[$id_forum]=$id_forum;

?>

<//B_remonte>

</BOUCLE_liste>
<hr>
</B_liste>

Et au final notre tutorial devient :

<?php
if(floor(phpversion()) < 4)	{
	// La version de PHP est inférieure à 4,
	// la fonction in_array n'existe donc pas
	function in_array($member, $array)
	{
		reset($array);
		while (list($k, $v) = each($array)) {
			if ($v == $member) return true;
		}
		return false;
	}
}
?>

<BOUCLE_principale(ARTICLES){id_article}>


<BOUCLE_compte_sujets(FORUMS){id_article}> </BOUCLE_compte_sujets>
<p>#PUCE Il y a #TOTAL_BOUCLE sujets en réponse à cet article</p>
</B_compte_sujets>


<BOUCLE_compte_messages(FORUMS){id_article}{plat}> </BOUCLE_compte_messages>
<p>#PUCE Il y au total #TOTAL_BOUCLE messages en réponse à cet article</p>
</B_compte_messages>

<hr>
<?php $tableau = array();?>
<BOUCLE_liste(FORUMS){id_article}{plat}{par date}{inverse}> 

<BOUCLE_remonte(FORUMS){id_enfant}>
<BOUCLE_remonte_rec(boucle_remonte)> </BOUCLE_remonte_rec>
</BOUCLE_remonte>
<?php 

$id_forum='[(#ID_FORUM|texte_script)]';
$titre='[(#TITRE|texte_script)]';
if(!in_array($id_forum,$tableau)) echo $titre."<br>";
$tableau[$id_forum]=$id_forum;

?>

<//B_remonte>

</BOUCLE_liste>
<hr>
</B_liste>



[<p><a href="forum.php3?(#PARAMETRES_FORUM)"> Nouveau sujet </a></p>]

<B_sujets>
<ul>
  <BOUCLE_sujets(FORUMS){id_article}{par date}{inverse}{0,5}>
  <li>#TITRE[ <a href="forum.php3?(#PARAMETRES_FORUM)"> répondre </a>]</li>
  <B_reponses>
  <ul>
    <BOUCLE_reponses(FORUMS){id_parent}{par date}>
    <li>#TITRE[ <a href="forum.php3?(#PARAMETRES_FORUM)"> répondre </a>]</li>
    <BOUCLE_recursive(boucle_reponses)>
    </BOUCLE_recursive>
    </BOUCLE_reponses>
  </ul>
  Il y a #TOTAL_BOUCLE réponses postées en réponse à cette r&eacute;ponse. 
  </B_reponses>
  </BOUCLE_sujets>
</ul>

</BOUCLE_principale>

Voilà vous savez tout, c’est grâce à ces notions qu’on peut réaliser un forum style phpBB en Spip

updated on 21 January 2007

Discussion

13 discussions

  • 2
    Ysengrin

    Bonjour,

    Voici le site : http://www.demain-la-terre.net

    Et voici mon souci :

    En Une du site nous affichons les “5 derniers commentaires”, lesquels, attention, peuvent être d’un article OU d’une brève.

    A l’origine, pas de problème : en cliquant sur le lien, on aboutissait à la page de l’article ou de la brève, c’est exactement ce que je veux.

    MAIS (tiré de http://www.spip.net/fr_article908.html) “#URL_FORUM donne, depuis [SPIP 1.8], l’adresse canonique de la page qui affiche le message de forum”. Et ça ça me plait pas du tout, c’est pas joli, moi, je veux arriver sur la page du texte !

    Quelqu’un saurait-il faire ça ? ? ?

    (j’ai cru trouvé une solution en renvoyant sur la page id = #PARAMETRES_FORUM... mais je coince encore une fois, puisque la page en question peut être brève OU article ! :-( )

    • Il suffit d’ajouter des boucles imbriquées dans ta boucle pour reperer si les messages viennent d’un article ou d’un breve ou quoi.

      Moi sur le bloog je fais ca :)
      http://zone.spip.org/trac/spip-zone...

    • Ysengrin

      Bon sang mais c’est bien sûr ! J’ai un peu pataugé, parce que je voulais extraire des éléments du commentaires, mais SPIP 1.8 le permet grâce aux Balises non ambiguës

      Merci beaucoup pour le coup de main.

    Reply to this message

  • 1
    Jcrusot

    Bonjour

    Je viens de passer des heures à chercher une solution à mon problème. J’ai crée un forum dans une page nomé perso_forum.php en y incluant la balise (#FORMULAIRE_FORUM

    L’affichage du formulaire se fait très bien ainsi que la prévisualisation du message, mais par contre le retour de l’envoie définitif du message se fait sur la page article.php3 alors que je la voudrais sur perso_forum.php avec en plus comme argument l’id_rubrique.

    Merci de votre aide
    Jcrusot

    • Essaye ca :

      #FORMULAIRE_FORUM{#SELF} ou bien #FORMULAIRE_FORUM{ma_page.php3}

      Avec spip 1.8 ou CVS

    Reply to this message

  • Jcrusot

    petite question annexe : le retour de l’envoie d’un message se fait toujours sur article.php ! Y-a-t-il un moyen de renvoyer le formulaire sur une autre page ?

    Merci

    Reply to this message

Comment on this article

Who are you?
  • [Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom