Drupal:如何动态设置活动菜单项

时间:2010-06-21 18:00:16

标签: drupal drupal-6 menu

例如,我有“node / 31”。如果查看node / 31,我希望drupal将菜单活动项设置为“galleries / lastgallery”。怎么做?

<?php
function custom_nodeapi (&$node, $op, $a3 = NULL, $a4  = NULL){
    if ($op == 'view' && $node->nid == 31) {
           ???
        }
}
?>

更新: 我知道我可以使用menu_set_active_item。但在这种情况下,将不会显示选项卡(查看/编辑等选项卡)。我认为应该使用menu_set_active_trails完成,或者可能以menu_get_item / menu_set_item某种方式完成,但我无法确定具体结果。

8 个答案:

答案 0 :(得分:8)

出于类似目的,我使用了menu_set_item()。您应该保留$path参数NULL,并将'galleries/lastgallery'的内部路径的菜单项用作$router_item

function custom_nodeapi(&$node, $op, $a3 = NULL, $a4  = NULL) {
  if ($op == 'view' && $node->nid == 31) {
    $path = drupal_get_normal_path('galleries/lastgallery');
    if($path && $menu_item = menu_get_item($path)) {
      menu_set_item(NULL, $menu_item);
    }
  }
}

答案 1 :(得分:4)

正如tmsimont所指出的,使用menu_set_item()会产生副作用......

快速查看menu_set_item()menu_get_item()向我们展示了它们触发挂钩和数据库调用()。不完美。

如果您正在使用Drupal 7.9+,那么有一个名为menu_tree_set_path()的新功能可以解决这个问题:

menu_tree_set_path('user-menu', 'shopping-cart');

第一个参数是菜单名称,后跟您要选择的路径。

注意:这不适用于.active类,而是应用.active-trail,因此您必须更新CSS以适应这两种情况!

答案 2 :(得分:2)

我知道我在游戏中有点迟了,这已经有了答案,但我想我会发布这个,以防有人帮助

参考menu_set_item(NULL,$ menu_item)杀死本地任务的问题 - 它不仅限于此。

我发现在使用discuss模块时它没有加载块。我认为问题在于做类似的事情:

$path = drupal_get_normal_path('galleries/lastgallery');
$menu_item = menu_get_item($path);
menu_set_item(NULL, $menu_item);

你有效地告诉drupal你在不同的页面/项目上。

对我有用的解决方案是:

$menu_item = menu_get_item();
$menu_item['href'] = 'galleries/lastgallery';
menu_set_item(NULL, $menu_item);

这似乎只是与href一起玩,只留下休息,所以本地任务仍然有效,disqus也是如此。

答案 3 :(得分:0)

我不确定您是否要更改活动项目以影响加载哪个页面(这需要在页面加载的早期完成以产生影响),或者您只是想表面突出显示“ galleries / lastgallery“链接好像是活动链接。

如果您只是想让它看起来好像“galleries / lastgallery”链接是活动链接,可以通过覆盖template_preprocess_page()功能来完成。在那里,您可以重建主要(或辅助)菜单并添加逻辑,以将“galleries / lastgallery”链接提供给“active”(和/或“active-trail”)类。

答案 4 :(得分:0)

通过结合使用menu_set_active_item(),我能够实现与您尝试做的事情类似的事情。 menu_execute_active_handler()

花了一点时间意识到我需要两者。我使用自定义菜单处理程序从Solr过滤器组合创建“干净的URL”。 $ path变量是我隐藏的内部drupal路径,菜单处理程序是用户在浏览器中看到的。

然后我使用custom_url_rewrite_outbound()将网站上的所有相关搜索链接转换为我想要的格式。

以下是代码的相关部分。我不确定这是不是你想要的,但它可能会给你一些想法。我对能够控制用户看到的内容以及Drupal在内部意识到的内容印象深刻。正确的菜单项是活动的,其他一切都按预期工作。

function myModule_search_menu(){
  $items['browse/%menu_tail'] = array(
    'title' => 'browse',
    'description' => 'Search Replacement with clean urls.',
    'page callback' => 'myModule_search_browse',
    'access arguments' => array('search content'),
    );
}

function myModule_search_browse(){
   /* do lots of fancy stuff */
   menu_set_active_item($path);
   return menu_execute_active_handler($path);
}

答案 5 :(得分:0)

mongolito404的回答几乎为我工作。

会杀死您的本地任务(标签)

出于某种原因,如果你在做mongolito404之前做的事情之前调用任务就行了......就像这样:

<?php

    //call local tasks first
    menu_local_tasks(0);    

    //then do what mongolito did    
    $path = drupal_get_normal_path('galleries/lastgallery');
    if($path && $menu_item = menu_get_item($path)) {
      menu_set_item(NULL, $menu_item);
    }
?>

答案 6 :(得分:0)

你可以试试这个:

function menu_tree_set_path($menu_name, $path = NULL)

答案 7 :(得分:0)

您也可以使用hook_translated_menu_link_alter()

/**
 * Implements hook_translated_menu_link_alter()
 */
function Module_translated_menu_link_alter(&$item, $map) {

    if ($item['menu_name'] == 'menu-name') {

        //check first two arg from url
        $path = arg(0)."/".arg(1);

        //add class active-trail if path match
        if (strpos($item['link_path'], $path) !== false) {
            $item['in_active_trail'] = true;

        }

    }
}