Реализация "active"-состояния нужного элемента меню

Главные вкладки

Аватар пользователя STINGER STINGER 30 ноября 2009 в 2:45

Здравствуйте. Пытаюсь сделать главное меню на сайте. Элементов в меню 7-10 максимум. Все страницы сайта подвязаны с помощью таксономии к любому из элементов меню. Т.е. любая страница сайта - дочерняя страница какого-то из главных терминов таксономии (может через промежуточные термины), каждый из которых (главных терминов) является отдельным элементом главного меню сайта. Пример структуры:

Главный термин №1
-- дочерний термин (уровень 2) №1
-- дочерний термин (уровень 2) №2
----- дочерний термин (уровень 3) №1
----- дочерний термин (уровень 3) №2
-- дочерний термин (уровень 2) №3

"Главный термин №1" является одним из пунктов главного меню сайта.

Так вот хочу добиться, чтобы если какая-то из нод принадлежит "дочернему термину (уровень 3) №2" и пользователь находится на этой странице, в главном меню сайта пункт "Главный термин №1" имел CSS-класс "active", чтобы я мог задать ему соответствующий стиль.
Жду ответов. Заранее спасибо.

Комментарии

Аватар пользователя STINGER STINGER 30 ноября 2009 в 2:51

Если быть точнее, то мне нужно, чтобы класс "active" присваивался элементу списка < li >, которыми собственно строится меню.

Аватар пользователя STINGER STINGER 1 декабря 2009 в 3:25

Stan.Ezersky wrote:
Menu Trails

Поставил, сконфигурировал, не работает. Когда заходишь дальше категории, которая в меню стоит, класс "active" пропадает...

Аватар пользователя Alangasar Alangasar 1 декабря 2009 в 9:54

Я делал в template.php
Выдернул с рабочего сайта, сорри, думаю идея понятна.
<?php
function тема_preprocess_page(&$vars) {
if (preg_match("/works/", request_uri())){
menu_set_active_item('taxonomy/term/1');}
}
?>

Аватар пользователя STINGER STINGER 20 декабря 2009 в 19:46

Alangasar wrote:
Я делал в template.php
Выдернул с рабочего сайта, сорри, думаю идея понятна.
<?php
function тема_preprocess_page(&$vars) {
if (preg_match("/works/", request_uri())){
menu_set_active_item('taxonomy/term/1');}
}
?>

так, теперь после апгрейда до v6.15 такой код рушит полностью мое Primary links, перекашивая его, пункты меню пропадают, само меню залазит вверх на хэдэр... короче полный break дизайна. До этого (при v6.14) в template.php было прописано так:

<?phpfunction моя_тема_preprocess_page(&$variables) {
  if ($variables['node']->type == "story") {
    $variables['template_files'][] = 'page-node-story';
  }
  if ($variables['node']->type == "page") {
    $variables['template_files'][] = 'page-node-page';
  }
  if (preg_match("/news/", request_uri())){ 
  menu_set_active_item('news');
  }
}?>

Т.е. последнее условие - для подсветки меню "News" классом active, первые два - кастомные тэмплэйты для разных типов нод. Кто может сказать почему эта комбинация не работает в новой 6.15 версии Друпала и как сделать аналогичное, чтобы работало в этой версии.

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

Аватар пользователя STINGER STINGER 1 декабря 2009 в 19:46

"Stan.Ezersky" wrote:
Там другой класс от Menu Trails, посмотрите код

Я знаю, я просто коротко написал суть. Пропадает этот класс при навигации вглубь разделов...

Alangasar wrote:
Я делал в template.php
Выдернул с рабочего сайта, сорри, думаю идея понятна.
<?php
function тема_preprocess_page(&$vars) {
if (preg_match("/works/", request_uri())){
menu_set_active_item('taxonomy/term/1');}
}
?>

Идея понятна, но уж больно частный случай... ненапишешься таких кодов для каждой категории... да и не всегда пути к нодам содержат путь материнского термина, а просто подвязаны к нему. Поэтому вариант "просто сверки путей родительского термина и ноды" не подходит.

Аватар пользователя STINGER STINGER 6 декабря 2009 в 4:32

В общем получается, но не полностью. Не пойму почему, но походу модуль фигово делает то, что предлагает сконфигить в своих настройках. Объясню: в настройках можно выбрать привязку любого термина из любого словаря к определенному пункту меню. Что само собой предполагает, что когда заходишь в привязанный к пункту меню термин, этот пункт меню должен получать active-класс! Но фиг там. В самих нодах этот класс имеется, а в терминах которым они принадлежат - нет.

Конкретный случай у меня: есть словарь "Новости" и в нем куча тегов новостей. Когда в новость заходишь, пункт меню "Новости" имеет соответствующее активное состояние. А когда заходишь в любой из тегов новости (один из терминов словаря "Новости") активного состояния меню как и не бывало.

Не знаю у меня ли это просто так, но я так понял функционал в админке модуля по привязке терминов к пункту меню не работает. При навигации в новость меню "Новости" имеет активный класс только из-за того, что конфиге модуля в "Node types" типа материала "Новость" привязан к соответствующему пункту меню.

Короче багов хоть лопатой греби в этом модуле (он еще и игнорит словари, в которых включены тэги, чтобы заставить показать такой словарь пришлось закомментировать 2 строки в файле модуля и толку то... все равно не работает...)

Так что все еще жду помощи в решении вопроса "придачи активного состояния нужному пункту меню"

Аватар пользователя Dan Dan 21 декабря 2009 в 20:11

Попробуйте привязывать ноду ко всему дереву терминов (хотя это идеологически не очень верно), то есть:
Главный термин №1
-- дочерний термин (уровень 2) №1
----- дочерний термин (уровень 3) №1
по этому пути нода должны быть привязана ко всем терминам.

Аватар пользователя STINGER STINGER 22 декабря 2009 в 12:15

"Dan" wrote:
Попробуйте привязывать ноду ко всему дереву терминов (хотя это идеологически не очень верно), то есть:
Главный термин №1
-- дочерний термин (уровень 2) №1
----- дочерний термин (уровень 3) №1
по этому пути нода должны быть привязана ко всем терминам.

Извините, но это уже бред получается... мне нужно структурировать контент (для чего и нужна таксономия), а то, что вы предлагаете, сделает кашу полную...

Аватар пользователя Dan Dan 22 декабря 2009 в 20:35

"STINGER" wrote:
Извините, но это уже бред получается... мне нужно структурировать контент (для чего и нужна таксономия), а то, что вы предлагаете, сделает кашу полную...

Нет, не бред. Это может быть лишним при некоторых реализациях, но это, по сути, эмуляция запроса /taxonomy/term/123/all - вывести все ноды термина 123 и всех его подтерминов.
К тому же непонятно почему Вы считаете это бредом. Рассмотрим такую категоризацию:

Категории:
- Ноутбуки
-- Acer
--- Серия Timeline
Нода:
"Модель 5810" (привязана к термину "Серия Timeline").
По-вашему привязка ноды к термину "Ноутбуки" - бред? Мало того, если у термина "Ноутбуки" будет термин (tid), например 5, то запрос /taxonomy/term/5/all выдаст нам, в числе прочего и ноду "Модель 5810", даже если она привязана к термину "Серия Timeline".

Привязку ко всей линейке терминов делает http://drupal.org/project/hierarchical_select

Ещё попробуйте TaxonomyMenu, только он кривой имхо...

Аватар пользователя STINGER STINGER 23 декабря 2009 в 2:28

Dan, да, убедили. Но вот как быть если в меню пункт - это "вид представления" (view) определенного словаря, которому принадлежат все остальные термины в структуре? Т.е. по умолчанию в друпале же нельзя сделать вывод содержимого словаря, как термина ему принадлежащего, например, т.к. для него не существует публично пути, только через админку. Приходится юзать Views.

А когда юзаешь модули для задания тэгов у нод (тот же Active Tag), можно задать создание тэга (термина) лишь в определенном словаре, не термине. Соответственно без Views нельзя, например, сделать структуру типа (если не создавать все тэги-термины вручную через админку = гемор):

Словарь Новостей:
- Новости (главный термин, которому присваиваются все новости, и по его адресу будет выводится новостная лента)
--Тэг новостей 1
--Тэг новостей 2
--Тэг новостей 3 и т.д.

Вместо этого приходится юзать такое:

Словарь Новостей: (для вывода новостной ленты создать Views по этому словарю)
-Тэг новостей 1
-Тэг новостей 2
-Тэг новостей 3 и т.д.

В итоге, при использовании Views пункт меню — ссылка на вьюс, а не на элемент таксономии, так что при навигации глубже него его "активное" состояние теряется, т.к. вся эта магия "таксономического дерева" не работает.
Ссори что так много расписал, просто одна из конкретных ситуаций именно такова.

Частично, и как частный случай это можно было решить (если соблюдается четкая иерархия пути) способом, которым тут выше поделился Alangasar:

<?php
function тема_preprocess_page(&$vars) {
if (
preg_match("/works/"request_uri())){
menu_set_active_item('taxonomy/term/1');}
}
?>

Но у меня это перестало работать после последнего обновления движка до v6.15.

Поэтому вопрос по-прежнему остается актуальным...

Аватар пользователя Dan Dan 23 декабря 2009 в 3:21

В taxonomy_menu вроде создаётся пункт меню для словаря. Поковыряйте его, вдруг, что-то получиться.

А вообще, при хитрых трюках с таксономией надо делать свой обработчик её терминов. В роли обработчика - свой модуль или контриб, например views. Обработчик можно установить с помощью хука [ru-api=hook_term_path] или модулем Taxonomy Redirect (это как бэ GUI к этому хуку).

(сдаваться рано Smile

Аватар пользователя STINGER STINGER 23 декабря 2009 в 4:00

"Dan" wrote:
В taxonomy_menu вроде создаётся пункт меню для словаря. Поковыряйте его, вдруг, что-то получиться.

А вообще, при хитрых трюках с таксономией надо делать свой обработчик её терминов. В роли обработчика - свой модуль или контриб, например views. Обработчик можно установить с помощью хука hook_term_path или модулем Taxonomy Redirect (это как бэ GUI к этому хуку).

(сдаваться рано :)


Ну так сдаваться никто и не планировал, сделато-то все равно как-то нужно, и тему эту не создавал бы тогда Smile Спасибо, насчет таксономии поковыряюсь.

Но вот насчет задания menu_set_active_item('') определенному пункту меню согласно URL по методу, предложенному Alangasar'ом, все равно думаю нужно было решить в Друпале v6.15, с учетом еще задания в function тема_preprocess_page кастомных теплэтов для определенных типов материалов, поэтому вот код, который у меня заработал:

<?php
function название_темы_preprocess_page(&$variables, &$vars) {
  if (
$variables['node']->type == "news") {
    
$variables['template_files'][] = 'page-style-news';
  }
  if (
$variables['node']->type == "page") {
    
$variables['template_files'][] = 'page-style-page';
  }
  if (
preg_match("/news/"request_uri())){ 
  
menu_set_active_item('news');
  }
}
?>

*Это если кто-то столкнется с подобной проблемой.

Аватар пользователя Dan Dan 23 декабря 2009 в 6:58

С меню в друпале засада - слишком много на него навесили имхо и шаг влево/вправо не позволителен.