Данная решение является следствием неграмотной и необдуманной постановки задачи.
ЗАДАЧА:
Изначально необходимо было сделать 4-е обычных меню которые указывают на различные материалы. И все! Но после этой элементарной работы (когда меню уже было сформировано) заказчик пожелал "немного" усовершенствовать навигацию на сайте.
Теперь:
- меню должно быть не простым, а выпадающим. (Ну это конечно не проблема, можно использовать замечательный модуль Nice Menus просто подправив css.)
- меню должно отображаться каждое в своем разделе. Т.е. Если раньше выводились все блоки меню на любой странице, то теперь нужно их выводить только там где выводится материал из этого меню.
РЕШЕНИЕ:
Какие могут быть тут варианты?
- прописать в настройках блока где нужно выводить тот или иной блок, а где нет - очень долго да и не правильно
- сделать первичное (primary links) и вторичное меню (secondary links) и выводить их в разных местах. Но! Меню у нас уже сделано и надо все перенабирать, да и с Nice Menus могут возникнуть осложнения
- в «установках видимости для страницы» ввести PHP код который будет регулировать появление блока. Попытался придумать алгоритм, но не смог разобраться как определить какое меню находится в данном блоке (может кто знает?)
- написать сниплет который будет выводить нужный блок меню на нужной странице. Собственно это и сделаем.
Для того чтобы определить какой блок нам нужно показывать мы создадим один блок в который по некому условию и будем выводить нужное меню. Старое меню мы трогать не будем (я имею ввиду его структуру и наполнение). И создадим меню с верху которое будет типа первичным (primary links), но не совсем. Верхнее меню будет содержать ссылки на ноды (node) аналогичные тому меню, которое будет выведено нашим сниплетом.
Т.е есть меню
О нас
О нас – node/1
Контакты – node/2
Цены – node/3
и меню
Аудит
Аудит, консалтинг – node/4
Налоги – node/5
Экспертиза – node/6
Значит верхнее меню будем делать
О нас (node/1) Аудит (node/4)
После создания меню можно приступить к сниплету. Итак каков алгоритм? Алгоритм прост.
- Определить активное меню (то в котором мы находимся)
- Вывести меню
Код
Получить идентификатор текущего меню можно с помощью
//возвращает массив элементов текущего меню
$active_trail =_menu_get_active_trail();
?>
$active_trail[0] будет содержать нужный нам идентификатор.
Теперь вывести его с помощью самого простого на мой взгляд способа наполнения блока
$block = module_invoke('menu', 'block', 'view', <идентификатор_меню>);
print $block['content'];
?>
Вот и все
$active_trail =_menu_get_active_trail();
$block = module_invoke('menu', 'block', 'view', $active_trail[0]);
print $block['content'];
?>
Проверяем. Я не проверял у себя сразу для Nice Menus писал.
Собственно осталось теперь все это с выпадающим меню проделать. Конечно для начала нужно создать необходимое количество nice меню блоков.
Теперь все упирается в определении идентификатора меню родительского в nice menus. Но тут тоже все просто, после анализа таблицы variable все сразу становится ясно.
nice_menus_number – хранит общее количество меню
nice_menus_menu – хранит меню родитель.
Код очевиден
$active_trail =_menu_get_active_trail();
for ($i=1; $i <= variable_get('nice_menus_number', '2'); $i++) {
if (variable_get('nice_menus_menu_'. $i, '2') == $active_trail[0]) {
$block = module_invoke('nice_menus', 'block', 'view', $i);
print $block['content'];
}
}
?>
Осталось скрыть все остальные блоки и можно проверять.
В очередной раз поражен гибкости друпала!
НЕДОСТАТКИ:
- C модулем localizer работать не будет
- Это не совсем как предлагает Sa_Bo_Nim в "Создание логичного меню в Drupal"
Интересуют другие варианты решения данной задачи, ну и замечания конечно.
Комментарии
А у Вас вот картиночка, которая "До" - как вы сделали так, чтобы в каждом отдельном блоке раскрывался пункт меню, которое в шапке? Никак мой моСК не додумается сам, а вот решаю сейчас именно такую задачу... Буду очень благодарен.
Решил модулем Menu_Block. Спасибо
модуль context
Благодарю, попробую на досуге.