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

问题描述 投票:1回答:8

例如,我有“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,但我无法确定究竟是多少。

drupal drupal-6 menu
8个回答
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);
    }
  }
}

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
投票

我知道我在游戏中有点晚了,这已经有了答案,但我想我会发布这个以防万一

参考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也是如此。


0
投票

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

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


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

0
投票

你可以试试这个:

function menu_tree_set_path($menu_name, $path = NULL)

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

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;

        }

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.