Я переношу с 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 упоминания о таком типе меню вообще нет.
Кто уже сталкивался с данной проблемой, расскажите каким образом её решили? Или может кто-нибудь идейку подкинет, а то тяжко каждый раз при изменении адреса удалять и заново ставить модуль.
Комментарии
там вроде было функция menu_rebuild() или как-то так - не то, что нужно?
Думаю лучше начать http://api.drupal.org/api/function/hook_menu/6 (
А в случае смены путей лучше чистить кэш меню через dev модуль
С http://api.drupal.org/api/function/hook_menu/6 я уже начинал, описанный там тип меню "MENU_DYNAMIC_ITEM" не работает в 6 версии, больше подходящих способов там не нашёл, все другие заносят адрес сразу в базу и больше ни о чём не парятся ;(
Кеш чистить через модуль dev идея хорошая, я не знал что в нём есть такая функция, пока что буду использовать, спасибо за подсказку.
Функция menu_rebuild() тоже очищает кэш, но это по-моему не совсем оптимальный способ - при каждой загрузки страницы подчищать кэш. Хотелось бы найти более цивилизованный способ, например drupal ищет в кэше адрес и, если такой не находится, то уже начинает пробегаться по модулям и смотреть кто бы из них этот адрес скушал бы.
Здесь http://drupal.org/node/102338 были? Может быть, последний пункт "Upgrading to the new menu system" поможет - http://drupal.org/node/103114
http://drupal.org/node/103114 - да, это я уже читал но так и не разобрался где в массиве идёт отличие динамического от постоянного пункта. Сейчас ещё раз перечитал и всё-равно не понял Уже всяческие варианты перепробовал и всё-равно - до ручного сброса меню никаких изменений не подхватывает Drupal.
Можете привести пример рабочего динамического меню без лишнего текста, просто например по адресу /module1 вызывалась функция module_mainpage(). И чтобы при изменении в тексте модуля в массиве items[] названия с module1 на module2 сразу (без ручного сброса кэша меню) вызывалась функция по адресу /module2?
Вобщем пока работаю через функцию очистки кэша модуля Devel, лучшего способа не нашёл.
Ещё вопрос появился по теме меню: в документации приведен пример перехода на новую систему меню
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 тоже информации о такой функции нет. Может кто знает, авторы перепутали функцию или просто ещё не успели её реализовать в рабочем виде?
мне тоже нужно было подобное сделать, я написал функцию вот кусок из нее, думаю остальное сам поймеш
<?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
?>