Bonjour à tous, je viens demander votre aide sur l’affichage de menu, qui ne peux passer que par du code je pense.
J’ai ma liste de Primary links :
P1 - P2 - P3 -P4
Ces 4 Primary links dans leur bloc sont affichés dans l’entête de la page.
Chaque Primary link entraine des sous menus :
sous-menu P1 / sous-menu P2 etc (avec eux même des sous menus possibles)
Cette liste s’affiche dans le bloc navigation à gauche.
Mon problème est qu’il répète toute la liste des menus avec les Primary links, et les sous menus.
J’aimerai que lorsque’on clique sur un primary links dans l’entête, a gauche apparaisse seulement la liste de ses sous-menus déroulé.
J’espère que je suis clair.
Je voulais modifier la fonction menu_tree() directement mais je n’y arrive pas.
Merci de votre aide
- Vous devez vous identifier ou créer un compte pour écrire des commentaires

Le mieux est de créer un module ou un bloc personnalisé qui n’affiche que le menu local (défini comme celui de niveau 2 sous le «primary link» qui correspond à la page courante).
Comment est affiché le bloc «Navigation» ?
Pour cela, nous allons essayer de créer un bloc personnalisé. Notre point de départ : la fonction menu_block() du module «menu», qui se charge d’afficher le menu de navigation «normal». L’affichage du bloc dans cette fonction se fait ainsi :
<?php$item = menu_get_item($delta);
$data['subject'] = check_plain($item['title']);
$data['content'] = theme('menu_tree', $delta);
return $data;
?>
La fonction centrale est en fait
theme('menu_tree', $delta)qui execute, par défaut, la fonction theme_menu_tree(). Cette fonction affiche un arbre de menu. Le paramètre$deltaest ici simplement le numéro d’item du menu (ou$mid) du menu parent. Par défaut, le$middu menu «Navigation» est «1».Reproduisons le bloc navigation de base
Dans «Construction du site» / «Bloc», on ajoute un bloc. Format d’entrée «PHP», pour pouvoir coder quelque chose. Pour afficher exactement la même chose que le bloc «Navigation», on rentrerait, sur le modèle ci-dessus, le simple bout de code suivant :
<?phpecho theme('menu_tree', 1);
?>
Résoudre enfin notre problème
Pour créer un bloc qui n’affiche que le «primary menu» de base, il nous faut d’abord déterminer l’item de menu actif. Pour cela, nous allons d’abord charger le «primary menu» :
<?php$item = menu_get_item(variable_get('menu_primary_menu', 0));
?>
Puis nous allons parcourir les enfants de cet item de menu (ie. les éléments tout en haut du «primary menu») pour trouver celui qui est actif. En language Drupal, on appelle cela être «sur la piste active» (in active trail), c’est à dire être le parent du menu actif :
<?php$active_mid = 0;
foreach($item['children'] as $child_id) {
if (menu_in_active_trail($child_id)) {
$active_mid = $child_id;
break;
}
}
?>
Enfin, il ne nous reste plus qu’à afficher les enfants du menu actif :
<?phpif ($active_mid) echo theme('menu_tree', $active_mid);
?>
Récapitulons
Au final, notre bloc utilise donc le code suivant :
<?php$item = menu_get_item(variable_get('menu_primary_menu', 0));
$active_mid = 0;
foreach($item['children'] as $child_id) {
if (menu_in_active_trail($child_id)) {
$active_mid = $child_id;
break;
}
}
if ($active_mid) echo theme('menu_tree', $active_mid);
?>
Et voila :)
Damien Tournoud
808
C’est exactement cela.
Merci pour cette réponse parfaite ^^
J’ai rien à ajouter, chapeau !
PS : je reviendrais :-)
Zan
43
Hello,
Est-ce la seule façon de faire ?
La solution de damz est impecc, mais pas hyper facile à mettre en oeuvre pour un débutant. Vu que la demande de cet utilisateur doit être assez répandue (bcp de sites utilisent le modèle de navigation qu’il décrit), n’y a-t-il pas un autre moyen ? Par exemple, n’a-t-on pas un bloc généré automatiquement avec les «secondary links» (et ensuite, on règle Drupal de sorte que «secondary links» puise ces liens dans «primary links») ?
Vincent
Formations Drupal pour WEBMASTERS, DESIGNERS et DÉVELOPPEURS.
drupalfrance
1772
C’est une bonne idée. Malheureusement, si on peut créer un bloc pour un menu (donc pour celui désigné comme «Primary Links»), on ne peut pas créer de bloc pour les primary & secondary links en tant que tels.
De plus, si c’était le cas, ces menus s’afficheraient deux fois sur le thème (ie. une fois au niveau des secondary links et une fois dans un bloc). Et cela fait perdre en outre la possibilité d’avoir d’autres liens en tant que secondary links (comme par exemple les liens en bas de page sur ce site).
Donc je ne pense pas vraiment qu’il y ait d’autres méthodes. Mais tu as raison sur le fond, ce mode de navigation est tellement courant qu’il faudrait prévoir un module pour faire cela.
Damien Tournoud
808
D’ailleur, j’ai trouvé sur d.o une solution plus économe, qui s’appuie sur le fait que Drupal a déjà calculé la piste active lorsqu’il affiche le bloc :
<?php
// get the menu items that lead to the current menu item
$active_trail =_menu_get_active_trail();
// get the menu id of the active top-level link
$mid = $active_trail[0];
// get the primary menus id
$pmid = variable_get('menu_primary_menu', 0);
//do they match?
if ($active_trail[0] == $pmid)
echo theme('menu_tree', $active_trail[1]);
?>
Cela évite l’itération sur le menu primaire, mais le principe reste identique.
Damien Tournoud
808
Merci beaucoup pour tes recherches, damz !
J’utilise souvent cette organisation de menus sur mes sites, et ce code me sera bien utile.
Vincent
Formations Drupal pour WEBMASTERS, DESIGNERS et DÉVELOPPEURS.
drupalfrance
1772
C’est vrai que c’est une navigation très utilisée.
j’aurais servi a quelque chose par ici ^^
Merci Damz
Zan
43
Très utile en effet mais par contre je ne parviens pas à faire fonctionnner ce système sur un site (et donc un menu) multilangue…
Quelqu’un a-t-il déja essayé ?
Adri
4
Salut,
Je vient justement de poster sur drupal.org deux modules qui réalisent cette fonctionnalité.
Le menu désiré est sectionné en un bloc par profondeur, puis chaque bloc est disponible dans la section d’administration des bloc, il n’y a plus qu’a les placer (simple comme bonjour !).
le module «Sliced Menu» s’attaque aux menus standards et «Sliced Book Navigation» permet la même chose mais avec la navigation d’un livre.
A noter qu’il faut définir le menu ou book à prendre en compte dans la section admin des modules.
alwex
15
Hello alwex,
Je suis très intéressé par l’utilisation de ton module que je suis déja en train de tester. L’as-tu essayé avec du multi-langue ?
Comment doit-on faire pour modifier le template de ces block ? Peut-on appliquer un template différent selon le niveau ?
Merci !
Adri
4
Salut Adri,
Au niveau du multi-langue, je ne sais pas encore.
Les blocs sont tout à fait personalisable via CSS, chaque bloc possédant une classe différents en fonction de son niveau.
<ul class="book_block_1">.
.
</ul>
<ul class="book_block_2">
.
.
</ul>
ect...
Le module Sliced Book Navigation est utilisé sur ce site :
http://groovnco.free.fr
Comme tu peu le voir, une partie de la navigation est à gauche et l’autre sous forme d’onglet au dessous des titres des pages.
alwex
15
Et sous D6, ça se passe comment à présent pour ce même problème ?
Merci.
Drupalfr.org est aussi sur freenode à #drupal-fr
—
Amipicto communication et publicité
floown@drupal.org
910
Bonjour,
Le module Menu Bloc : http://drupal.org/project/menu_block permet de faire pile-poil ce que tu cherches.
saradimi
56