Хозяйке на заметку: активные трейлы с модулем Menu Block

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

Аватар пользователя areafix areafix 9 ноября 2009 в 17:01

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

Существует очень достойный модуль Menu Block. С его помощью очень легко режется иерархическое меню на блоки заданной глубины. А еще существует очень достойный модуль Taxonomy Menu. С его помощью очень легко делаются иерархические меню на основе некоего выбранного словаря. Не знаю, как другие, но я очень люблю нанизывать структуру сайта на словарь с незамысловатым названием "Структура сайта" и, пользуясь этими двумя модулями, делать навигационное меню.

Однако, drupal имеет одну неприятную фичу/багу, которая сводится к тому, что если у нас пункт меню (не важно, чем он сделан) ведет на страницу термина таксономии, то при переходе к материалу, в дальнейшем, полностью теряется информация о пути меню (и хлебных крошках), которые ведут к данному материалу.

Ситуацию с хлебными крошками позволяет исправить очень достойный модуль Custom Breadcrumbs с активированной функцией "Use the taxonomy hierarchy to set the breadcrumb trail for nodes and taxonomy pages", однако галочка в его настройках "Force the active trail" к никаким полезным изменениям не приводит.

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

Проблема облегчается тем, что автор Menu Block очень грамотный программист и думает о нас, поставив перед началом обработки:

  // Allow other modules to alter the tree before we begin operations on it.
  drupal_alter('menu_block_tree', $tree, $context);

Этим и воспользуемся, взяв код kosilko за основу. Нам нужно, чтобы в древовидной структуре массива меню $tree, возвращаемого функцией menu_tree_page_data() были правильно расставлены единички по полям [in_active_trail]. Код от kosilko для этого вполне подходит, остальное делается через собственный модуль.

Во первых, описание модуля, создадим файл menu_block_at.info и впишем в него:

name = Menu Block Active Trails
description = Support module for menu block trails.
core = 6.x
dependencies[] = menu_block

Далее нам нужен собственно модуль, делаем файл menu_block_at.module:

<?php

function menu_path_menu_block_tree_alter(&$tree, $context) {
        foreach ($tree as $key => $links) {
                if ((strpos($_GET['q'],$links['link']['href'].'/')===0)) {
                        $tree[$key]['link']['in_active_trail'] = isset($links['link']['in_active_trail]']) ? $links['link']['in_active_trail'] : '1';
                }
                else {
                        if (!isset($aliases[$links['link']['href']])) {
                                $aliases[$links['link']['href']] = url($links['link']['href']);
                        }
                        if ((strpos($_GET['q'],$aliases[$links['link']['href']].'/')===0) || ($_SERVER['REQUEST_URI'] != $aliases[$links['link']['href']] && strpos($_SERVER['REQUEST_URI'],$aliases[$links['link']['href']].'/')===0)) {
                                $tree[$key]['link']['in_active_trail'] = isset($links['link']['in_active_trail]']) ? $links['link']['in_active_trail'] : '1';
                        }
                }
                if ($links['below']) {
                        menu_path_menu_block_tree_alter(&$tree[$key]['below'], $context);
                }
        }
}

Сохраняем оба файла в sites/ваш_сайт/modules/menu_block_at и активируем модуль. Может быть потребуется сбросить кеш на странице производительности. Собственно, все.

Комментарии

Аватар пользователя Negor Negor 7 октября 2010 в 0:53

Видимо многое изменилось после этого поста. В новой версии 6,19 не работает. Я уже изменил название процедуры, она же должна начинатся с имени модуля, так? Кроме того, в модуле menu_block вызов функции отличен от приведённого и имеет вида

<?php // Allow other modules to alter the tree before we begin operations on it.
  
$alter_data = &$tree;
  
// Also allow modules to alter the config.
  
$alter_data['__drupal_alter_by_ref'] = array(&$config);
  
drupal_alter('menu_block_tree'$alter_data);?>

Можно ли применить ваш совет, и с какими изменениями?