Bonjour tous,
J'ai un petit souci en PHP que je vais essayer de vous décrire ici, car je n'arrive pas à trouver une solution satisfaisante :
Je m'occupe de la remouture d'un site Intranet prévu pour 2000 utilisateurs à peu près. La presque entièreté du site est gérée de manière dynamique. Ainsi, pour mes "onglets de navigation", je vais chercher dans une table "menu" (identifiée par "ID" et qui contient notamment un champ "parent" qui est une référence interne vers "ID" ), tous les éléments du menu qui n'ont pas de parent (parent = '0').
Au moment où je clique sur un des liens ainsi générés, je dois afficher tous les sous-menu, c'est-à-dire du niveau 1, qui ont comme parent l'ID du niveau 0 que je viens de cliquer.
Exemple :
+- Menu ID=1 ; parent = 0
....+-> Menu ID=4, parent = 1
....+-> Menu ID=5, parent = 1
+- Menu ID=8 ; parent = 0
....+-> Menu ID=10, parent = 8
....+-> Menu ID=17, parent = 8
Je clique sur le premier lien, j'arrive sur index.php?id=1 . Le menu secondaire s'affiche, qui me propose les menu ID 4 et 5. Je clique sur le 5, je me retrouve sur index.php?id=5. Jusque là tout est normal et ça fonctionne du reste très bien.
Je ne suis pas techniquement limité et je peux avoir une infinité de niveaux en profondeur.
Mais maintenant arrive le problème: le niveau 0 étant mon "top menu", il est en réalité constitué d'une liste (<ul> ) formatée en CSS de sorte à se présenter sous forme de "boutons" (mais ce bien toujours des liens). Quand un menu est "actif", il change de couleur, classique.
Je check cela tout simplement (je tente de simplifier mon code au max : )
Code :
- // Je passe dans une boucler tous les éléments de niveau 0,
- // qui sont correctement stockés (ID et label) via une requête dans le tableau arrayZero[]
- echo "<li ".($_GET['id']==$arrayZero['id']?"class='active'":"" ).">
- <a href='index.php?id=".$arrayZero['id']."'>".arrayZero['label']."</a></li>";
- // "li.active" est la classe CSS qui formate le lien en apparence d'un bouton d'une autre couleur
|
Tout fonctionne à merveille pour le niveau 0.
MAIS évidemment, si je clique par exemple sur le Menu ID 10 (fils du 8), eh bien bien sûr le Menu ID 8 n'est plus en class "active" (puisque le code n'identifiera plus du tout le ID 8 dans l'URL... ) !
J'ai trouvé plusieurs manières de contourner ce problème, mais aucune ne me plaît :
- La première, la plus évidente: aller voir qui est l'aïeul de l'item en cours. Mais c'est ultra lourd : Si je suis dans un niveau 5, cela veut dire que je dois faire 5 requêtes successives (X est le parent de Y, qui est le parent de Z, etc. jusqu'à ce que parent=0 ), juste pour avoir l'affichage que je veux! Cela ne me plaît pas.
- Mettre le niveau 0 en variable $_GET du genre le lien ne va pas vers index.php?id=10 mais vers index.php?level0=8&id=10 ... pas très heureux, et au moment où je construis tous mes liens, je dois taper le niveau en dur ou aller le chercher par une requête, ce qui est un peu lourd (surtout quand le document ID 8 peut très bien être déplacé comme fils du 1 par après).
- J'ai pensé mettre en session une variable de type $_SESSION['level0'], qui ne changerait que si l'on change de niveau 0. Pas mauvaise idée, si ce n'est que, dans l'ordre chronologique, au moment où je dois choisir si le <li> est de classe "active" ou pas, la seule info que j'ai c'est l' "id" qui se trouve en $_GET via mon URL. Or, changer une variable de $_SESSION en fonction du click devrait donc se faire AU MOMENT du click, par exemple avec une fonction JavaScript style onClick. Or, client-side technology oblige, JS ne peut pas intervenir sur les variables de session.
- Construire une sorte de table dynamique qui reprend pour chaque page, quel que soit son niveau, quel est son parent de niveau 0 ... Cela implique d'une manière ou d'une autre que cette table doit être mise à jour à toute modif qui est effectuée, ou alors via un cron, mais c'est vraiment pas élégant ...
Bref, je suis un peu perdu. Dans quelques CMS que j'ai analysés, j'ai remarqué que le "active menu tab" n'était pas supporté partout, je suppose donc que ce n'est pas une "issue" si facile .. L'exemple le plus frappent étant Drupal, qui est pourtant bien coté .. Eh bien regardez les tabs en haut, cliquez dessus : pas de changement de style quand vous en avez sélectionné un ... Spip, quant à lui, gère ça un peu à la bourrine en appelant tous les documents du menu "fr" par un nom qui comment par "fr_" .. mouais dans le genre flexibilité on a vu mieux (je dois pouvoir bouger les documents à tout moment).
Après un peu de googling la seule chose que j'ai trouvé résiderait dans l'utilisation d'une technologie asynchrone du style AJAX. Mais je ne connais pas encore bien cela et ne veux pas me lancer là-dedans pour le moment, et il me semble du reste que ce problème ne doit pourtant pas être si original et doit pouvoir se résoudre en client-server traditionnel, non ?
Est-ce que quelqu'un a une piste de comment réaliser ce que je veux, sans que ce soit un rouleau compresseur de lourdeurs pour la DB / la mémoire de mon serveur ?
Merci d'avance pour toute aide