web-dev-qa-db-ja.com

メニューにテーマを付けて、メニュー名のラッパーdivを作成するにはどうすればよいですか?

デフォルトのメニューテーマ関数はメニュー名を出力しません(以下を参照)。

function theme_menu_tree($variables) {
  return '<ul class="menu">' . $variables['tree'] . '</ul>';
}

$ variablesを調べましたが、メニュー名は含まれていません。その名前がラッパーdivに含まれるようにメニューにテーマを設定する方法を誰かが知っていますか?

5
Gus

theme_menu_tree() はテーマラッパー関数です。メニューツリーのレンダー配列がレンダリングされた後、つまり、レンダリングされた出力を変更する機会があった後に呼び出されます。

さらに、テーマラッパー関数に任意のデータを渡すことはできません。常に、子のレンダリングされた出力を受け取ります。

したがって、IDを持つラッパー_<div>_がある場合にやりたいことを行うには、メニューツリーのレンダー配列を変更して、それを追加する独自のテーマ関数を呼び出す必要があります。

実例

すべてのメニューブロック(メニューツリーの一般的なユースケース)でこれを実行しようとしているとしましょう: menu_block_view() ブロックのコンテンツに menu_tree($delta) 、ここで_$delta_は、たまたまブロックに対応するメニュー名です。

ここで、menu_tree()menu_tree_output() を呼び出します。これは、theme_menu_tree()を呼び出すレンダー配列が構築される場所です。

そのため、レンダー配列の作成後にブロックの内容を変更し、theme_menu_tree()を、_<div>_をIDで追加する独自のテーマ関数に置き換えます。これを行うには、 hook_block_view_alter() を実装します。

_/**
 * Implements hook_block_view_alter().
 */
function MYMODULE_block_view_alter(&$data, $block) {
  // Check to make sure this is a menu block
  if (in_array($block->delta, menu_get_names())) {
    // Replace the theme wrapper function with a theme function
    // and add the menu name to the render array
    unset($data['content']['#theme_wrappers']);
    $data['content']['#theme'] = 'MYMODULE_menu_tree_with_id__' . $block->delta;
    $data['content']['#menu_name'] = $block->delta;
  }
}
_

MYMODULEをモジュールの短い名前に置き換えます。実装したら、ラッパーを処理するテーマ関数theme_MYMODULE_menu_tree_with_id()を作成します_<div>_:

_/**
 * Implements hook_theme().
 */
function MYMODULE_theme() {
  $theme = array();
  $theme['MYMODULE_menu_tree_with_id'] = array(
    'render element' => 'element',
  );
  return $theme;
}

/**
 * Returns a menu tree with an id corresonding to the menu name.
 */
function theme_MYMODULE_menu_tree_with_id($variables) {
  $output = '<div id="' . $variables['element']['#menu_name'] . '">';
  $output .= '<ul class="menu">' . drupal_render_children($variables['element']) . '</ul>';
  $output .= '</div>';

  return $output;
}
_
5
user7