Drupal: как установить активный пункт меню динамически - PullRequest
1 голос
/ 21 июня 2010

Например, у меня есть "узел / 31". И я хочу, чтобы drupal установил активный пункт меню на «galleries / lastgallery», если просматривается node / 31. Как это сделать?

<?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 ]

8 голосов
/ 22 июня 2010

Для аналогичных целей я использовал 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 голосов
/ 13 марта 2012

Как указал 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 голосов
/ 24 мая 2012

Я знаю, что немного опаздываю в игре, и здесь уже есть ответ, но я решил опубликовать это на тот случай, если это кому-нибудь поможет

Со ссылкой на проблему menu_set_item (NULL,$ menu_item) уничтожение локальных задач - это не ограничивается этим.

Я обнаружил, что при использовании модуля обсуждения он не загружал блок.Я думаю, что проблема заключается в том, что, делая что-то вроде:

$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 голосов
/ 03 января 2018

Вы также можете использовать 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;

        }

    }
}
0 голосов
/ 17 мая 2012

Вы можете попробовать это:

function menu_tree_set_path($menu_name, $path = NULL)
0 голосов
/ 03 февраля 2011

Ответ 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 голосов
/ 26 июня 2010

Мне удалось добиться чего-то похожего на то, что вы пытаетесь сделать, используя комбинацию menu_set_active_item () и menu_execute_active_handler ()

Потребовалось немного времени, чтобы понять, что мне нужны оба.Я использовал пользовательский обработчик меню для создания «чистых URL» из комбинаций фильтров Solr.переменная $ 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 голосов
/ 22 июня 2010

Я не уверен, хотите ли вы изменить активный элемент, чтобы он влиял на то, какая страница загружена (что необходимо сделать в начале загрузки страницы, чтобы изменить ситуацию), или если вы просто хотите поверхностно выделить " galleries / lastgallery ", как если бы это была активная ссылка.

Если вы просто хотите, чтобы она выглядела так, как будто ссылка "galleries / lastgallery" является активной, это можно сделать, переопределив функцию template_preprocess_page () . Там вы можете перестроить основное (или вторичное) меню и добавить логику, чтобы дать ссылку на «galleries / lastgallery» класс «active» (и / или «active-trail»).

...