创建菜单链接以查看参数

时间:2010-08-05 13:37:41

标签: drupal menu hyperlink arguments

我正在尝试使用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!');
}

3 个答案:

答案 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假菜单路线,那么自己手动创建链接可能会更好。