Modificatiion de la table des catégories : Ajout du champ 'cat_parent_id' dans dc_categorie.

[mysql]
CREATE TABLE `dc_categorie` (
  `cat_id` int(11) NOT NULL auto_increment,
  `cat_libelle` varchar(255) NOT NULL default '',
  `cat_desc` longtext,
  `cat_libelle_url` varchar(255) NOT NULL default '',
  `cat_ord` int(11) default NULL,
  `cat_parent_id` int(11) default NULL,
  PRIMARY KEY  (`cat_id`),
  UNIQUE KEY `cat_libelle_url` (`cat_libelle_url`),
  UNIQUE KEY `cat_libelle` (`cat_libelle`)
) TYPE=MyISAM;

Comment exploiter cela ?

Faire une fonction pour remplacer dcCatList() et changer l'appel dans template.php

[php]
<?php 
// dcCatList() ;
dcCategorieTree::dcextCatListTree();
?>

la fonction dcextCatListTree()

Liste l'arboresence des catégories pour les presenter comme cela :

[xml]
<ul>
  <li class="xx"><a href="...">categorie 1</a></li>
  <li class="xx"><a href="...">categorie 2</a></li>
  <li class="xx"><a href="...">categorie 3</a>
    <ul>
      <li class="xx"><a href="...">sous-categorie 3.1</a></li>
      <li class="xx"><a href="...">sous-categorie 3.2</a></li>
    </ul>
  </li>
  <li class="xx"><a href="...">categorie 4</a></li>
</ul>

la balise <li> est marquée par une class qui peut prendre les valeurs suivantes

  • class="actif" pour la catégorie activée
  • class="open" pour une catégorie non activée contenant la catégorie active
  • class="normal" pour une catégorie non activée ne contenant pas la catégorie active

naturellement il peut exister une infinité de niveaux (des sous-sous catégories)

Limitations :

  1. incompatibilité avec le plugin multicat seul la catégorie principal d'un billet est prise en compte
  2. seules les catégories contenant au moins un billet sont affichées
  3. seul l'ordre mentionné dans la table *_catégorie est pris en compte

Une seule requete SQL est necessaire (pas de recursivité)

La requete :

[php]
$strReq  = 'SELECT DISTINCT C.cat_id, cat_libelle, cat_desc, cat_libelle_url, cat_parent_id, cat_ord, count(P.post_id) AS nb_post'; 
$strReq .= ' FROM '.DB_PREFIX.'categorie C LEFT JOIN '.DB_PREFIX.'post P ON ((C.cat_id = P.cat_id) )'; 
$strReq .= ' WHERE 1 AND P.post_pub = ' . (integer)$blog -> pub_mode . ' ';
$strReq .= ' GROUP BY cat_id ORDER BY cat_ord DESC';

Et oui l'astuce c'est de parcourir la liste à l'envers avec une boucle et d'affecter une case de tableau avec le code correspondant à chaque catégorie :

[php]
while (!$rs->EOF()) {
    $aStr1[cat_parent_id] .= '<li><a href='cat_url' >cat_libelle</a>'.<ul>'.$aStr1[cat_id].'</ul>';
    $rs->moveNext();
}

Bon là c'est en version simplifiée, mais ça marche (la preuve ... ce blog)