我正在尝试使用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!');
}发布于 2010-08-06 21:03:27
我设法回答了我的问题。基本上,我使用了与我在视图中设置的路径不同的路径,然后使用views_page()作为我的“页面回调”。我向它传递了视图的参数、页面ID和它自己的附加参数,以使视图正常工作。我能够在菜单项中使用通配符传递给views_page(),方法是使用与hook_menu()配合使用的to_arg()函数传入通配符。“页面参数”在三个参数中传递。最后一个参数"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;
}
?>发布于 2010-08-06 02:55:39
我没有太多在自定义模块中使用通配符URL的经验,但我在Pro Drupal Development一书中研究了这个问题。根据我在"Wildcards and Parameter Replacement" section on page 77中读到的内容,我认为您可能希望使用$items‘’view path/%‘来代替。使用%dest显然会使drupal寻找dest_load函数。
发布于 2010-08-06 03:03:55
出现在菜单中的项目不能由通配符路由器项目创建:每个菜单项恰好对应于一条路径。也就是说,如果您有一个路由器项是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()中,它将在每个页面上执行检查:这是为了确保它在菜单重建后触发。这应该不会对性能造成太大影响,但请记住这一点。
正如你所看到的,这是一个漫长而漫长的过程:如果你不打算走视图-假菜单的路线,最好是自己手动创建链接。
https://stackoverflow.com/questions/3415203
复制相似问题