Отображение иерархический словарей в одно меню, но при использовании разных view

Аватар пользователя Xermit Xermit 25 февраля 2011 в 14:41

Не предлагать Hierarchical или taxonomy menu, так как у меня свой модуль который вырос из taxonomy menu еще под 5-й друпал. Надеюсь подскажите.

Есть два словаря (c пунктами у которых есть несколько родителей)
VocA
A
D
B
D
C

VocB
E
F

есть View-хи ViewA для VocA и ViewB для VocB

вывести надо меню

VocA_VocB
A
D
B
D
C
VocB
E
F

У меня свой код который создает пункты меню.

Хочется, чтобы пункты меню одного словаря имели свой prefix url, чтобы к ним прицепить нужную View-ху созданную для конкретного словаря.

При этом, чтобы пункты словаря можно было отобразить в любой пункт меню.
Точнее сказать с возможностью сведения в один подпункт пунктов или разделов разных словарей, но отображать словари разными View-хами.

Что пробовал:

Пункт VocA_VocB пробовал создать как обычный пункт меню, создал страницу и сделал пункт.
То есть в меню есть пункт VocA_VocB для страницы http://site/voca_vocb

Когда программно создаю свои подпункты, задаю им в качестве пути:
voca_vocb/A
voca_vocb/A/D
и так далее
увы подпункты эти не появляются

Кроме всего прочего надо сделать так чтобы для этих подпунктов из словаря VocA запускалась ViewA при просмотре.

Попробовал сделать по другому.

Пункт меню VocA_VocB создал программно для url voca_vocb, создав фиктивный словарь VocA_VocB

при создании пунктов меню для VocA словаря
указываю url такие
voca_vocb/voca/A
voca_vocb/voca/A/D

Учтите что пункт меню для url voca_vocb уже создан, а пункта меню для url voca_vocb/voca нет.

Такой фокус естественно не прокатывает, прокатывает если я только создаю промежуточный пункт
меню voca, но мне как раз в пункте VocA_VocB промежуточный подпункт VocA не нужен, а пункты словаря VocA сразу включить в пункт VocA_VocB. Еще нужно, чтобы при выборе пунктов меню A, A/D был префикс voca, чтобы я мог в ViewA указать url страницы voca_vocb/voca/%.

Может мне стоит создать voca подпункт фиктивным типа view_page, но только не видимым? Можно ли такое определить? Например callback пункт меню, а не как я делаю сейчас все мои пункты как NORMAL_MENU_ITEM? И появятся ли тогда пункты A, A/D в пункте VocA_VocB, если пункт VocA не будет видимым, т.е. CALLBACK_MENU_ITEM?

Если это получится, тогда я смогу задать нужную view для нужных пунктов, а в url будет voca после voca_vocb и до A, A/D
и пункт по идее видимым не будет.

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

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

0 Thanks

Комментарии

Аватар пользователя Xermit Xermit 27 февраля 2011 в 21:29

В общем остановился на следующем варианте.
Остался фиктивный словарь без терминов
VocA_VocB
по нему модуль выводит общий пункт меню с url voca_vocb
Для словаря VocA запрещаю создание обобщающегося пункта меню из названия словаря,
одновременно указывая url voca_vocb/voca, который используется при создании пунктов меню этого словаря. Например для D будет создан пункт с url voca_vocb/voca/D
То чего я как раз добивался, чтобы было слово voca в url
Далее в ViewA я прописываю url voca_vocb/voca/%
а в поле Предоставить параметры если они не переданы указываю код, чтобы выцепить параметры из url-a:

$path = explode('/', drupal_get_path_alias($_GET['q']));
foreach($path as $value)
{
  array_shift($path);

  if ($value == 'voca')
  {
    break;
  }
}

$view->args = $path;
return $path;

а в валидаторе

$result_arg ='';
foreach($view->args as $arg)
{
  if (is_numeric($arg))
  {
    $result_arg .= $arg . ",";
  }
  else
  {
    $term = taxonomy_get_synonym_root($arg);
    if ($term)
    {
      $result_arg .= $term->tid . ",";
    }
  }
}

if (!empty($result_arg))
{
  $handler->argument = substr($result_arg, 0, -1);
}
else
{
  $handler->argument = "all";
}

return TRUE;

При этом для каждого такого пункта меню приходится указывать

следующую структуру чтобы view запустилась

//$path = voca_vocb/voca/D
$items[$path] = array(
  'access arguments'=> $access,
  'description'     => t($term->description),
  'path'            => $path,
  'title'           => $name,
  'weight'          => $term->weight,
  'access callback' => TRUE,
  'page callback'   => 'views_page',
  'page arguments' => array($view_name, 'page_1'),
  'type'            => MENU_NORMAL_ITEM

Таким образом даже не имея корневого пункта меню куда прицеплины термины для всех этих терминов будет использована моя view для отображения.

В случае когда термины словаря VocB выводятся в свой подпункт VocB
все проще, все термины выводтся как обычные пункты меню без указания view
и лишь для корневого пункта указано, что он выводится через view
соответственно когда удет выбран термин друпал найдет корневой пункт меню по иерархии путей и вызовет view нужную мне.

В итоге в одном подпункте удалось по разному собрать пункты меню разных словарей и при отображении используются разные view.

Аватар пользователя Xermit Xermit 18 апреля 2012 в 3:40

Маленькая поправка для случая когда на сайте есть вью, а пункты меню созданы по иерархическому словарю, но доступны только через определенный вью сайта. То есть, при нажатии на пункт меню, вам нужно чтобы drupal перешел к нужной вью и передал в нее нужные параметры.
Для такого случая следует page_arguments передавать так

'page arguments' => array_merge(array($view_name, 'page_1'), get_view_args($url_path.'/%', $rpath? $rpath: $path)),
function get_view_args($view_path, $path)
{
        return explode('/', preg_filter("#^".str_replace("%", "(.*)", $view_path)."\$#", "$1", $path));
}