web-dev-qa-db-ja.com

hook_menu()を使用して作成するメニュー項目の親を設定するにはどうすればよいですか?

データベースの値に基づいて一連のメニュー項目を動的に作成する必要があります。

これが私のhook_menu()関数の例です。このスニペットでは、DBクエリを削除し、配列を追加して概念を証明しました。

function MYMODULE_menu() {
  $years = array(2011, 2010, 2009);

  foreach ($years as $year) {
    $items['events/' . $year] = array(
      'title' => $year . ' Events Archive',
      'page callback' => 'page_archive',
      'page arguments' => array(1),             
      'access callback' => TRUE,
      'type' => MENU_NORMAL_ITEM,
      'menu_name' => 'main-menu',
    );  
  }

  return $items;
}

これが機能し、メインメニューに2011 Events Archive2010 Events Archiveおよび2009 Events Archiveというタイトルの3つのメニュー項目が表示されます。

私が抱えている問題は、メインメニューツリーで動的に作成されるメニュー項目の位置です。それらはトップレベルに表示されますが、親Eventsメニュー項目の下に表示したいです。

現在、メニューツリーは次のようになります。

  • ホーム
  • イベント
  • 私たちに関しては
  • お問い合わせ
  • 2011年のイベントのアーカイブ
  • 2010年イベントアーカイブ2009年イベントアーカイブ

次のようになります。

  • ホーム
  • イベント
    • 2011年のイベントのアーカイブ
    • 2010年のイベントアーカイブ
    • 2009年のイベントアーカイブ
  • 私たちに関しては
  • お問い合わせ

ログイン時にメニューエディターUIを使用してメニュー項目を移動できることを知っていますが、これらはシステムによって自動的に作成されるため、それらは、人間の介入なしにイベントの下に自動的に表示される必要があります。

これはどのように行うことができますか?これを行う簡単な方法はありますか?

5
Camsoft

Eventsメニュー項目はノードにリンクしているため、eventsはパスエイリアスであるため、次のコードを使用してメニュー項目を定義すると、達成しようとしていることが機能するはずです。 (ノードIDとして「11」を使用しています)。

function MYMODULE_menu() {
  $years = array(2011, 2010, 2009);

  foreach ($years as $year) {
    $items['node/11/' . $year] = array(
      'title' => $year . ' Events Archive',
      'page callback' => 'page_archive',
      'page arguments' => array(1),             
      'access callback' => TRUE,
      'type' => MENU_NORMAL_ITEM,
      'menu_name' => 'main-menu',
    );  
  }

  return $items;
}

eventsnode/11のパスエイリアスの場合、Drupalが展開されないためevents/2011 to node/11/2011。同様に、events/editnode/11/editに展開しませんNodeモジュールはnodes /%node/editをメニュー項目の1つとして定義しています).

6
kiamlaluno
<?php
/**
 * GOAL AND STRATEGY:
 *
 * node/6 is a top level menu item in a custom menu called 'menu-main-menu'. I'm
 * creating a child menu item using hook_menu with the path of 'member/pick'. I
 * want this menu item to be rendered as a child of node/6 in the main menu, and
 * I want all of this to happen programatically.
 * 
 * Here's how...
 * 
 * 1. Create the child item using hook_menu
 * 2. In hook_menu_link_alter, lookup the mlid of node/6 and apply it as the
 * plid of the child item
 * 
 */

/**
 * Implementation of hook_menu()
 */
function hook_menu() {
  $items = array();
  $items['member/pick'] = array(
    'title' => 'Member Pick',
    'menu_name' => 'menu-main-menu',
    'page callback' => 'member_pick_page',
    'access callback' => TRUE,
    'type' => MENU_NORMAL_ITEM,
  );    
  return $items;
}

/**
 * Implementation of hook_menu_link_alter
 */
function hook_menu_link_alter(&$item) {
  if ($item['page callback'] == 'member_pick_page') {
    $parent_normal_path = 'node/6';
    $plid = db_result(db_query("SELECT mlid FROM {menu_links} WHERE link_path = '%s'", $parent_normal_path));
    $item['plid'] = $plid;
  }
}
2
Aaron Klump

これが私のやり方です...まず、グループを表すメニュー項目を作成します:

$items['admin/content/example'] = array(
  'title' => 'Example menu group',
  'page callback' => 'example_page_2011',
  'access arguments' => array('administer nodes'),
);

次に、このグループの下にメニュー項目を追加します。

foreach ($years as $year) {
  $items['admin/content/example/' . $year] = array(
    'title' => $year,
    'page callback' => 'example_page_' . $year,
    'access arguments' => array('administer nodes'),
    'type' => MENU_LOCAL_TASK,
  );
}

イベントは機能しますが(7.22でテスト済み)、ページコールバックの冗長性はまだ好きではありません。 MENU_GROUPと呼ばれるタイプがあった場合のみ...より良い解決策がありがたいです。

0
stuchl4n3k