2009-12-03 13 views
5

我一直在阅读Drupal中的各种菜单功能,但有很多很多,我已经达到了一个完全混乱和绝望的地步...希望其中一个这里的聪明人可以帮助我...Drupal菜单系统 - 输出树一级关闭

基本上,我有四个级别菜单。我试图创建一个从第二层输出的树。

因此,菜单如下:LEVEL ONE>综A>综I>综一个

我试图输出与综A开头的菜单树 (即无底柱分段A>综I>综一)

但是,不能为我的生活弄清楚如何做到这一点...我试图仅仅让无底柱分段菜单的MLID(在这种情况下69),然后

<?php print theme_menu_tree(69); ?> 

但它只打印出'69'。根本不是我所期望的...

任何人都知道如何做到这一点?

+1

您不应该直接调用主题函数。 <?php print theme('menu_tree',69); ?> 本来是得到意想不到的结果的正确方法:) – Rimian 2009-12-06 04:21:54

回答

11

我总是想知道为什么在核心中没有这个功能,但afaik没有。

所以看起来我们需要推出我们自己的,走一个完整的菜单树,直到我们找到我们需要的子树:

/** 
* 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; 
} 

要使用它,你首先需要获得树的整个菜单,使用menu_tree_page_data()menu_tree_all_data(),这取决于你需要什么(检查差异的API定义)。然后根据mlid提取你想要的子树。此子树然后可以通过menu_tree_output()呈现为HTML:

$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); 

免责声明:我不知道这是做一个好/有道 - 这就是我想出了一个解决方案在经历与OP相同的过程之后,即通过阅读整个菜单模块的功能,总是想知道我是否错过了明显的某处...

+0

当我今天早些时候看到这个问题时,我决定不回答,因为我本来能够给出的唯一答案就是沿着这些路线,似乎是错误的方法。现在你发布了你的答案,我不知道我是否必须开心,因为我得出的结论与你的结论相同,或者不愉快,因为没有更好的方法来做到这一点。总之:+1。 – mac 2009-12-03 22:55:42

+0

主题子菜单输出的最佳方式是什么? – 2010-09-28 15:27:38

+0

@matt ryan:'menu_tree_output()'已经返回一个主题菜单,所以我不确定你的意思。如果您想影响它创建输出的方式,请查看该函数的链接API文档页面 - 它使用'theme_menu_item_link','theme_menu_item'和'theme_menu_tree'来实现此功能。 – 2010-09-28 15:56:01

13

Menu Block模块将完全按照您的需要进行操作。 (它使用与上述自定义函数类似的逻辑)。

+1

+1 - 良好的捕获。可能很好地保存OP一些编码:) – 2009-12-04 00:06:29

+0

+1 - 确实很不错! :) – mac 2009-12-04 18:49:46

1

仍然在自定义功能的路径上...今天 - 为什么寻找完全不同的东西 - 我发现另一个同事面临同样的问题,并提出了另一个解决方案。

原帖是here。以下是该代码段中的代码段。

// 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); 
    } 
}