Как установить активный пункт меню?

Аватар пользователя Обухов Никита

Здрасте.

Не могу понять, как это нужно сделать. Суть такая, есть довольно сложное меню с навигацией по каталогу товаров (с помощью Views). Разумеется, к любой ноде можно прийти несколькими путями из этого меню.

Суть в чем. Путь node/1 Друпалу вообще ни о чем не говорит. Как можно установить активный элемент пути при просмотре нод?

У меня есть 2 мысли:

1) Во Вьюс переписать ссылки на ноды, то есть вместо ссылок node/1 будет node/1/arg1/arg2/arg3 и по этим аргументам вычислять как юзер к нам попал, и выбирать активный пункт меню.

2) Пересылать пользователя не на node/3 а на /arg1/arg2/arg3/node/3
При этом в arg1/arg2/arg3 будет показан список нод для этого пункта меню, а при добавлении к пути node/3 выводить ноду. Тогда вроде как роутер Друпала вообше сам догадается, какой пункт меню сделать активным.

Может, есть другие варианты? Как это вообще правильно делается?

Ключевые слова:
Версия Drupal:
0 Спасибо

Комментарии

Аватар пользователя Обухов Никита
Обухов Никита 7 лет назад

Выходит, лучше добавить в БД свою таблицу, с адресами нужных элементов меню и ID нод, т.к. каждый раз копаться в таблицах menu_router и menu_links будет ресурсоемко.

0 Спасибо
Аватар пользователя Cherenkevich
Cherenkevich 7 лет назад

Я оффтоп. Не ругайся.

Слушай, ты бы рассказал общественности, как такие вьюхи сложные делать ) Я честно не догоняю, как так делать.

0 Спасибо
Аватар пользователя restyler
restyler 7 лет назад

Я обычно просто определяюсь, какая навигация на сайте - главная. Например, знаю что навигация - это дерево таксономии. Когда кликаешь на ноду, надо выделять в навигации тот термин, к которому нода принадлежит. Делается через вызов menu_set_item. Что-то типа того.. за точность кода не ручаюсь:
<?php
$item['href'] = 'taxonomy/term/' . $term -> tid;
menu_set_item(NULL, $item);
?>
Но этот путь возможно не подойдет, если надо отслеживать пути, пройденные пользователем.

Еще есть http://drupal.org/project/menutrails

0 Спасибо
Аватар пользователя Обухов Никита
Обухов Никита 7 лет назад

Cherenkevich, я неверно выразился - View там самый обыкновенный, с 4 аргументами и 4 полями и с 4 Display (для каждого раздела свой). А вот меню строится в модуле, в 2-х словах не объяснить, код выложить не могу. Может, когда закончу работу напишу здесь что и как.

restyler, спасибо, уже сделал по-другому. В самом Вьюс ссылки на ноды переписаны на accessories/1/2/3/4/NID
Т.к. аргументов может быть неизвестное число, то если заданы только arg(1) (например), то остальные заполняются нулями: accessories/1/0/0/NID.

<?php
// Это Views-темплейт поля Node Title 
  
$p $_GET['q'];
  
$parts explode('/'$p);
  
$number_parts count($parts);

  while ($number_parts 5) {
    
$p .= '/0';
    
$number_parts++;
  }
  
$output l($row->{node_title}, $p '/' $row->{nid}); 
  print 
$output;

?>

Вот так вывожу ноду по нужному адресу:

<?php
// Просто node_page_view использовать не получится, т.к. аргументов неизвестное число и какой из них NID - неясно.
  
$items['accessories/%/%/%/%/%'] = array (
    
'title' => 'Title',
    
'page callback' => 'mymodule_node_page_view',
    
'page arguments' => array('accessories',1,2,3,4,5),
    
'access arguments' => array('access content'),
    
'menu_name' => 'menu-mymodule-catalog',
    
'type' =>  MENU_CALLBACK,
    );

function mymodule_node_page_view($a0$a1 NULL$a2 NULL$a3 NULL$a4 NULL$nid NULL) {
// Т.к. аргументов неизвестное число, загружаем ноду по последнему числовому аргументу.
  
if (is_numeric($nid)) {
    
$node node_load($nid);
  }
  elseif (
is_numeric($a4)) {
    
$node node_load($a4);
  }
  elseif (
is_numeric($a3)) {
    
$node node_load($a3);
  }
  elseif (
is_numeric($a2)) {
    
$node node_load($a2);
  }
  elseif (
is_numeric($a1)) {
    
$node node_load($a1);
  }
  if (
$node->nid) {
      
// Удаляем все, что после последнего слэша.
      // На этом этапе мы уже на странице ноды, т.е. ?q=accessories/1/2/3/4/NID
      
$path preg_replace('/\/([^\/]*)$/'''$_GET['q']);
      
// Удаляем все нулевые аргументы.
      
$path str_replace('/0',''$path);
      
// Т.о. юзер пришел из $path. Ставим его активным в меню:
      
menu_set_active_item($path);
      
$additional = array(
        
=> array(
          
'title' => $node->title,
          
'path'  => $node->nid,
        ),
      );
      
mymodule_views_set_title_and_bread(TRUE$additional);
      return 
node_page_view($node);
  }
  else return 
drupal_not_fount();

}
?>

0 Спасибо
Аватар пользователя gorr
gorr 7 лет назад

Путь, который предложил restyler плох тем, что зачастую, в зависимости от места где выполняется эта функция, может привести к неверному рендерингу страницы. Например, на странице ноды могут не отобразиться локальные пункты меню.

0 Спасибо
Аватар пользователя gorr
gorr 7 лет назад

Обухов Никита, а зачем ты строку accessories аргументом передаешь? Вот тут: 'page arguments' => array('accessories',1,2,3,4,5), она не нужна.

0 Спасибо
Аватар пользователя restyler
restyler 7 лет назад
gorr написал:
Путь, который предложил restyler плох тем, что зачастую, в зависимости от места где выполняется эта функция, может привести к неверному рендерингу страницы. Например, на странице ноды могут не отобразиться локальные пункты меню.

локальные пункты меню - это какие? вроде не наблюдал таких проблем. вообще система меню в друпале та еще.. для подстраховки можно юзать в _nodeapi('view') вместо _init хука

0 Спасибо
Аватар пользователя gorr
gorr 7 лет назад

Я имел ввиду LOCAL_MENU_TASK, и прошу прощения, был невнимателен, Вы написали menu_set_item, а проблемы у меня лично возникали при menu_set_active_item, которая выставляла нужный вроде-бы путь для отображения блоков меню, но терялись нужные элементы на странице, те-же ссылки для редактирования нодов. Пришлось отказаться от этого пути.

0 Спасибо
Аватар пользователя Advanced
Advanced 7 лет назад

А какой тогда способ использовать? И как можно решить эту проблему с local tasks?

0 Спасибо
Аватар пользователя cracker@drupal.org
cracker@drupal.org 7 лет назад

Совсем недавно столкнулся с похожей проблемой. При переходе на страницы с путями 'news/2/3', 'news/2/4', 'news/2/5' нужно было, чтобы активным оставался пункт меню с путем 'news/2/3'. При выводе страниц 'news/2/4', 'news/2/5' использовал функцию menu_set_active_item('news/2/3'), где 'news/2/3' путь пункта меню, которого нужно сделать активным.

0 Спасибо