2009-12-03 9 views
5

J'ai lu les différentes fonctions du menu dans Drupal, mais il y en a tellement, et j'ai atteint un point de confusion et de désespoir ... Espérant que l'un des les smarties ici peuvent m'aider ...Système de menus Drupal - Sortie d'un arbre vers le bas

Fondamentalement, j'ai quatre niveaux à mon menu. J'essaie de créer un arbre qui sort du second niveau.

Ainsi, le menu ressemble à ceci: NIVEAU UN> Sublevel A> Sublevel I> Sublevel un

Je suis en train de sortie le début arborescence du menu avec Sublevel A (c.-à-Sublevel A> Sublevel I> Sublevel a)

Mais, ne peut pas pour la vie de me comprendre comment faire ... J'ai essayé de simplement obtenir le mlid du menu Sublevel a (dans ce cas 69), puis

<?php print theme_menu_tree(69); ?> 

mais il affiche juste '69'. Pas du tout ce que j'attendais ...

Quelqu'un sait-il comment faire?

+1

Vous ne devez pas appeler une fonction de thème directement. Rimian

Répondre

11

Je me suis toujours demandé pourquoi il n'y a pas de fonction pour ce noyau, mais il n'y en a pas.

Il semble donc que nous devons rouler notre propre, marcher un arbre de menu complet jusqu'à ce qu'on trouve le sous-arbre dont nous avons besoin:

/** 
* Extract a specific subtree from a menu tree based on a menu link id (mlid) 
* 
* @param array $tree 
* A menu tree data structure as returned by menu_tree_all_data() or menu_tree_page_data() 
* @param int $mlid 
* The menu link id of the menu entry for which to return the subtree 
* @return array 
* The found subtree, or NULL if no entry matched the mlid 
*/ 
function yourModule_menu_get_subtree($tree, $mlid) { 
    // Check all top level entries 
    foreach ($tree as $key => $element) { 
    // Is this the entry we are looking for? 
    if ($mlid == $element['link']['mlid']) { 
     // Yes, return while keeping the key 
     return array($key => $element); 
    } 
    else { 
     // No, recurse to children, if any 
     if ($element['below']) { 
     $submatch = yourModule_menu_get_subtree($element['below'], $mlid); 
     // Found wanted entry within the children? 
     if ($submatch) { 
      // Yes, return it and stop looking any further 
      return $submatch; 
     } 
     } 
    } 
    } 
    // No match at all 
    return NULL; 
} 

Pour l'utiliser, vous devez d'abord obtenir l'arbre pour le menu entier , en utilisant menu_tree_page_data() ou menu_tree_all_data(), en fonction de ce dont vous avez besoin (vérifiez les définitions API pour la différence). Ensuite, vous extrayez le sous-arbre que vous voulez, basé sur le mlid. Cette sous-arbre peut alors être rendu en HTML via menu_tree_output():

$mlid = 123; // TODO: Replace with logic to determine wanted mlid 
$tree = menu_tree_page_data('navigation'); // TODO: Replace 'navigation' with name of menu you're interested in 
// Extract subtree 
$subtree = yourModule_menu_get_subtree($tree, $mlid); 
// Render as HTML menu list 
$submenu = menu_tree_output($subtree); 

Avertissement: Je ne sais pas si cela est une bonne façon/bon de le faire - il est juste la solution que je suis venu avec après avoir suivi la même procédure que l'OP, c'est-à-dire lire toutes les fonctions du module, en me demandant toujours si l'élément qui me manque ...

+0

Quand j'ai vu la question plus tôt aujourd'hui, j'ai décidé de ne pas répondre parce que la seule réponse que j'aurais pu donner était le long de ces lignes, Fausse Route. Maintenant que vous avez posté votre réponse, je ne sais pas si je dois être heureux parce que je suis arrivé à la même conclusion que vous, ou malheureux parce qu'il n'y a pas de meilleure façon de le faire. De toute façon: +1. – mac

+0

Quelle est la meilleure façon de thématiser la sortie du sous-menu? –

+0

@matt ryan: 'menu_tree_output()' renvoie déjà un menu à thème, donc je ne suis pas sûr de ce que vous voulez dire. Si vous voulez influencer la façon dont il crée sa sortie, regardez la page liée api doc pour la fonction - il utilise 'theme_menu_item_link',' theme_menu_item' et 'theme_menu_tree' pour cela. –

13

Le module Menu Block fera exactement ce dont vous avez besoin. (Il utilise une logique similaire à la fonction personnalisée présentée ci-dessus).

+1

+1 - bonne prise. Pourrait bien sauver l'OP un peu de codage :) –

+0

+1 - Nice one indeed! :) – mac

1

Encore sur le chemin des fonctions personnalisées ... Aujourd'hui - pourquoi chercher quelque chose de totalement différent - J'ai trouvé un autre collègue confronté au même problème et proposant une autre solution.

Le message original est here. Ce qui suit est le c & p de l'extrait de code là.

// will return all menu items under "administration". 
print theme('menu_tree_by_path','admin'); 

// will return links to all node submission forms 
print theme('menu_tree_by_path','node/add'); 

// return the correct menu array by path 
function menu_get_mid_by_path($path) { 
// oddly, menu_get_item accepts a path, but returns the parent id. 
    $menu = menu_get_item(null, $path); 
    if (isset($menu['children'])) { 
// so we have to extract the mid for theme_menu_tree from one of the child items 
    if ($pid = end($menu['children'])) { 
     $menu = menu_get_item($pid); 
     return $menu['pid']; 
    } 
    } 
} 

//theme the crap out of it 
function theme_menu_tree_by_path($path) { 
    if ($mid = menu_get_mid_by_path($path)) { 
    return theme('menu_tree', $mid); 
    } 
}