Каким образом можно создать динамический пункт меню в Drupal 6?

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

Аватар пользователя Murz Murz 13 августа 2007 в 9:52

Я переношу с Drupal 5 для Drupal 6.x (CVS) и в процессе переноса постепенно дорабатываю свой модуль. В Drupal 5 у меня было и корректно работало множество перехватов функции hook_menu по определённым путям (например /prj, /prj/%/view, /prj/%/page/% и т.д.). При переносе этих перехватов на Drupal 6 я обнаружил что Drupal берёт адреса только в момент установки модуля (когда делаешь его "enabled"), а если меняются данные перехваты уже в установленном модуле (например /prj/%/view сменил на /prj/%/show), то никаких изменений не происходит, Drupal 6 хранит все эти адреса в базе и видимо даже не пытается обратиться к функции модуля (я даже в функции поставил вывод строки диагностики (echo "my menu hook";) чтобы видеть вызывается ли вообще функция, но эта строчка так и не выводится.

Данный режим работы мне нужен впринципе только на момент разработки, в финальном модуле список адресов будет уже определён и будет хватать статических элементов.

В Drupal 5 и более ранних версиях был тип меню MENU_DYNAMIC_ITEM, который как раз служил для необходимых мне целей, но в исходниках Drupal 6 упоминания о таком типе меню вообще нет.

Кто уже сталкивался с данной проблемой, расскажите каким образом её решили? Или может кто-нибудь идейку подкинет, а то тяжко каждый раз при изменении адреса удалять и заново ставить модуль.

Комментарии

Аватар пользователя Murz Murz 14 августа 2007 в 10:25

С http://api.drupal.org/api/function/hook_menu/6 я уже начинал, описанный там тип меню "MENU_DYNAMIC_ITEM" не работает в 6 версии, больше подходящих способов там не нашёл, все другие заносят адрес сразу в базу и больше ни о чём не парятся ;(

Кеш чистить через модуль dev идея хорошая, я не знал что в нём есть такая функция, пока что буду использовать, спасибо за подсказку.

Функция menu_rebuild() тоже очищает кэш, но это по-моему не совсем оптимальный способ - при каждой загрузки страницы подчищать кэш. Хотелось бы найти более цивилизованный способ, например drupal ищет в кэше адрес и, если такой не находится, то уже начинает пробегаться по модулям и смотреть кто бы из них этот адрес скушал бы.

Аватар пользователя Murz Murz 14 августа 2007 в 12:06

http://drupal.org/node/103114 - да, это я уже читал но так и не разобрался где в массиве идёт отличие динамического от постоянного пункта. Сейчас ещё раз перечитал и всё-равно не понял Sad Уже всяческие варианты перепробовал и всё-равно - до ручного сброса меню никаких изменений не подхватывает Drupal.

Можете привести пример рабочего динамического меню без лишнего текста, просто например по адресу /module1 вызывалась функция module_mainpage(). И чтобы при изменении в тексте модуля в массиве items[] названия с module1 на module2 сразу (без ручного сброса кэша меню) вызывалась функция по адресу /module2?

Аватар пользователя Murz Murz 15 августа 2007 в 17:18

Вобщем пока работаю через функцию очистки кэша модуля Devel, лучшего способа не нашёл.
Ещё вопрос появился по теме меню: в документации приведен пример перехода на новую систему меню

<?php
function search_init() {
  // To remember the user's search keywords when switching across tabs,
  // we dynamically add the keywords to the search tabs' paths.
  if (arg(0) == 'search') {
    $keys = search_get_keys();
    $keys = strlen($keys) ? '/'. $keys : '';
    foreach (module_implements('search') as $name) {
      $title = module_invoke($name, 'search', 'name');
      $item = menu_get_item('search/'. $name);
      $item->title = $title;
      $item->access = user_access('search content') && $title;
      menu_set_item('search/'. $name, $item);
      menu_set_item('search/'. $name . $keys, $item);
    }
  }
}
?>

Так вот там используется функция menu_set_item(), которую мой Drupal не находит. Да и в API тоже информации о такой функции нет. Может кто знает, авторы перепутали функцию или просто ещё не успели её реализовать в рабочем виде?

Аватар пользователя oblivion oblivion 6 октября 2008 в 17:58

мне тоже нужно было подобное сделать, я написал функцию вот кусок из нее, думаю остальное сам поймеш
<?php
$name_requirement = "Project_";
$values['title'] = $name_requirement;
$values['description'] ='';
$values['expanded'] = 0;
$values['pid'] = 1; // root меню
$values['weight'] = 0;
$type = 'add';
drupal_execute("menu_edit_item_form", $values,$type);
menu_overview();
// а теперь чтоб изменения были видны
// я сделал редирект на какуюто страницу а потом опять обратно
// да это изврат но подругому никак, только F5
?>