5

The default menu theme function doesn't output the menu name (see below).

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

I've inspected $variables, and that doesn't contain the menu name. Does anyone know how I can theme a menu so that its name is in a wrapper div?

5

theme_menu_tree() is a theme wrapper function: it's called after the render array for the menu tree is rendered, and thus, after you have a chance to modify the rendered output.

Additionally, you can't pass any arbitrary data to a theme wrapper function: it'll always receive the rendered output of the children.

So to do what you want to do, where you have a wrapper <div> that has an ID, you need to modify the menu tree render array to call your own theme function that adds it.

Practical example

Let's say you're trying to do this for all menu blocks (a common use-case for menu trees): menu_block_view() populates the content of the block with menu_tree($delta), where $delta happens to be the menu name corresponding to the block.

Now, menu_tree() calls menu_tree_output(), which is where the render array that calls theme_menu_tree() is built.

So, what you want to do is modify the contents of the block after the render array is built, to replace theme_menu_tree() with your own theme function that adds your <div> with ID. To do that, implement 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;
  }
}

Replace MYMODULE with your module's short name. Once implemented, create the theme function theme_MYMODULE_menu_tree_with_id() to handle wrapper <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;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.