我正在尝试使用hook_menu来创建一个带有参数的视图的链接。但是,如果我使用我已经在视图中设置为路径的路径(在$items[view-path/%dest]
中),则链接不会出现。我猜测某处存在路径冲突。这有什么方法吗?或者我可以使用其他方法返回视图吗?
我正在使用以下代码:
/**
* implementation of hook_menu().
*/
function sign_custom_menu() {
$items['view-path/%dest'] = array(
'title' => 'Link to view',
'page callback' => 'sign_custom_hello',
'page arguments' => array(1), //(corrected typo from 'page arguements')
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
'menu_name' => 'menu-student-links',
);
return $items;
}
function dest_to_arg() {
// would normally be dynamic to get view with correct argument
$arg = 73;
return $arg;
}
提前致谢。
function sign_custom_hello() {
//return t('Hello!');
}
答案 0 :(得分:3)
我设法回答了我的问题。基本上我使用了与我在视图中设置的路径不同的路径,然后使用views_page()作为我的“页面回调”。我传递了视图的参数,页面ID以及它自己的附加参数以使视图工作。我能够在菜单项中使用通配符,通过使用与hook_menu()一起传递通配符的to_arg()函数传递给views_page()。 'page arguments'传递三个参数。最后一个参数“1”是对参数出现的路径中的哪个位置的引用(从0开始)。
工作代码是:
<?php
/**
* implementation of hook_menu().
*/
function sign_custom_menu() {
$items['view-path/%dest'] = array(
'title' => 'link to view',
'page callback' => 'views_page',
'page arguments' => array('view_name', 'page_1', 1),
'access callback' => TRUE,
'type' => MENU_NORMAL_ITEM,
'menu_name' => 'menu-student-links',
);
return $items;
}
//this function is needed from the "%dest" argument in hook_menu above
function dest_to_arg() {
// would normally be dynamic to get view with correct argument
$arg = 73;
return $arg;
}
?>
答案 1 :(得分:0)
我对自定义模块中的通配符URL没有多少经验,但我在Pro Drupal Development一书中研究了这个问题。根据我在"Wildcards and Parameter Replacement" section on page 77中的内容,我认为你可能想要使用$ items ['view-path /%']。使用%dest显然会使drupal查找dest_load函数。
答案 2 :(得分:0)
菜单中显示的项目无法通过通配符路由器项创建:每个菜单项仅对应一个路径。也就是说,如果你有一个foo/%bar
和%bar
的路由器项可以有10个不同的值,Drupal的菜单系统不会从一个路由器项定义中创建10个新的菜单项。
因此,您需要做的是提前为每个可能的参数创建一个路由器项。否则,您将不得不在Drupal的菜单系统外面查看,并考虑创建一个看起来像菜单的单独的视图块,但实际上是可用选项的视图无序列表。
要执行前者,您需要实现hook_menu_alter()
以在其他所有内容之后添加自定义路由器项,包括您尝试覆盖的通配符路由器项。您的自定义路由器项目或多或少与通配符路由器项目相同,但设置了一些通常从通配符派生的默认值。
例如,如果我想为user/1/edit
创建一个覆盖内置user/%user_category/edit
的新路由器项,我就会实现hook_menu_alter()
:
function mymodule_menu_alter(&$items) {
// user_edit and user_edit_access expect a user object
$account = user_load(array('uid' => 1));
$items['user/1/edit'] = array(
'type' => MENU_CALLBACK,
'page arguments' => array($account),
'access arguments' => array($account),
) + $items['user/%user_category/edit'];
}
在此示例中,user/%user_category/edit
分别为页面和访问回调调用user_edit()
和user_edit_access()
,并且它们都尝试使用通配符。由于路由器项目中没有通配符,因此您需要覆盖参数以说“检查用户1”。
您将为通配符的每个可能值执行此操作。
但这还不够:请注意我使用的是MENU_CALLBACK
而不是MENU_NORMAL_ITEM
。如果您使用MENU_NORMAL_ITEM
,即使您设置menu_name
(我不知道),您的路由器项目也会显示在导航菜单中,而不会显示在自定义菜单中为什么会这样:它应该工作)。但是你可以使用menu_link_save()
来解决这个问题。
考虑hook_init()
的实现:
function mymodule_init() {
$router_path = 'user/1/edit';
// Check to see if the custom router item has been added to menu_links.
// This is to ensure the menu has already been rebuilt.
$router_item = db_fetch_object(db_query("SELECT * FROM {menu_links} WHERE router_path = '%s'", $router_path));
// Only create a new menu item if the router item exists and it
// hasn't already been created (it's hidden until created).
if ($router_item && $router_item->hidden) {
$item = array(
'link_title' => 'Edit Administrator',
'link_path' => $router_path,
'menu_name' => 'primary-links',
'router_path' => $router_path,
'mlid' => $router_item->mlid,
);
// Save the menu item.
menu_link_save($item);
}
}
在此实现中,它会检查自定义路由器是否已创建且未进行其他修改。如果是这样,它会在主链接菜单中创建一个引用您的自定义路由器项的菜单链接。
显然,由于它位于hook_init()
,它会对每个页面执行检查:这是为了确保在重建菜单后触发。这不应该是性能损失,但要记住这一点。
正如您所看到的,这是一个漫长而漫长的过程:如果您不打算使用Views假菜单路线,那么自己手动创建链接可能会更好。