Theming Drupal primary links with child sub-menus

May 23, 2008

Using 'Primary links' for your Drupal site's main navigation menu is a great idea. However, most themes by default display primary links in such a way that if the menu has sub-child menus, they will not be displayed. Fortunately, the solution is much easier that you'd think.

First off, the way that most themes generate primary links is like so:

<? theme('links', $primary_links);

As mentioned, this will only output the top-level menu items, like so:

<ul>
  <li>Menu Item 1</li>
  <li>Menu Item 2</li>
  <li>Menu Item 3</li>
</ul>

That's not very useful for sites with a robust navigation tree.

To get around this, the simplest way is to remove the original theme() function outputing the primary links, and create a new region in your template where you'd like your navigation menu to show up. Then, you can assign the 'Primary links' block to that region, and the entire menu tree will be displayed there.

To create a region in Drupal 5:

You'll need to modify your theme's template.php file. If it doesn't yet have one, create it, and enter the following:

<?
function name_of_theme_regions() {
  return array(
        'name_of_new_region' => t('name of new region'),
   );
}

To create a region in Drupal 6:

In your theme's '.info' file, you'll need to define your new region. Put something like this:

regions[name_of_new_region] = name of new region

Be sure to replace 'name_of_theme' with the name of your theme, and 'name_of_new_region' with the name of your new region.

Outputting content of the new region

The key of the array item (or value in between brackets for Drupal 6) will be used as the variable name in your theme files, like '$name_of_new_region'.

The value of the array item (or value to the right of the equals sign for Drupal 6) will be used as the title of the region on the '/admin/build/block' page.

In your page.tpl.php file, output the content of the region like so:

<? if ($name_of_new_region) print $name_of_new_region;

Then, head over to '/admin/build/block' and set the 'Primary links' block to the region you just created.

Done!