I'm really confused with how to theme menus in Drupal 7 and I've found the Menu block module which is supposed to makes things simpler. Turns out it's not that simple for me.

I've created a Menu block called "myfooter" and thanks to the Menu block documentation page I was able to determine that the mytheme_menu_link__menu_block__myfooter() function seems to be acting on the menu. Huzzah.

But I don't know how to use it at all. It's not as if there was a $variables inside and I could var_dump the var to try and understand what's in it.

Currently, I'm only doing the following to check that it's actually replacing my menu items by a simple print statement:

function mytheme_menu_link__menu_block__myfooter() {
  print 'test string';

Basically, my problem is that Drupal outputs the menu with an unordered list structure that I don't need.

<ul class="menu">
  <li class="lots of classes here"><a href="/" title="" class="blah">Item1</a></li>
  <li class="lots of classes here"><a href="/" title="" class="blah">Item2</a></li>

How can I wipe it to simply print my items one after another, with a pipe sign or dash or whatever separator I wish? Is mytheme_menu_link__menu_block__myfooter() even sensible to achieve that?

I've found a bunch of Drupal menu functions in the API but they are all so confusing I feel like I should stick to what Menu block offers.

  • Anyone? I'm still stuck with this, unfortunately...
    – vanz
    Jan 28, 2013 at 12:35
  • If you have a theme function, the data is passed in through arguments. And the generated string has to be a return value, not a print statement.
    – donquixote
    Nov 8, 2013 at 11:05
  • The way this is usually achieved is not to change the HTML output but to style it as inline using CSS. There's no real need to alter the HTML output at all. Nov 8, 2013 at 11:41

3 Answers 3


Documentation for theme_menu_link():

function theme_menu_link(array $variables) {
  $element = $variables['element'];
  $sub_menu = '';

  if ($element['#below']) {
    $sub_menu = drupal_render($element['#below']);
  $output = l($element['#title'], $element['#href'], $element['#localized_options']);
  return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";

The generated html needs to be returned as a return value.

The $variables argument has all the data.

Instead of var_dump(), you should install devel and do a dpm($variables). You might have to refresh the page twice to see the result.


Finally discovered that I needed to use THEME_menu_tree to theme the parent ul and THEME_menu_link to theme the li. Not straight forward at all...


Another option is to use Menupoly and create your own MenuTheme class in a custom module or theme.

Pro: You can reuse this menu theme for different menus in different blocks, even across sites.

Con: You need code to define the block. And you need a bit of studying.

How to

The example module has some inspiration.
Incidentally, it already contains an example MenuTheme that does exactly what you want - a flat menu without ul list.

Next step is to define the block containing the menu.

 * Implements hook_menupoly()
function MYMODULE_menupoly() {
  return array(
    'flat_top' => array(
      'menu_name' => 'main-menu',
      'depth' => 1,
      // You can either use the MenuTheme class in menupoly_example, or copy it into your own module.
      'menu_theme' => new menupoly_example_MenuTheme_FlatLinksWithSeparator(' | '),

Note: Menupoly uses xautoload to load the MenuTheme classes (and other classes), with the PHP 5.2 compatibility mode.

  • (this might not be the most useful for you, but it might be helpful for others who are looking for alternatives)
    – donquixote
    Nov 8, 2013 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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