Theming Drupal primary links with child sub-menus

Posted 8 months ago in Drupal

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:

<?php 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!

12 Comments

Daniel Shanahan
7 months ago

Where is the 'admin/build/block' ?

BTW, I'm a newbie, even to web hosting (just purchased my first domain a few weeks ago).

7 months ago

Daniel,

You would find that page at:

http://domain.com/admin/build/block

if 'domain.com' where the domain where you installed your Drupal codebase.

Nick

Daniel Shanahan
7 months ago

Thanks Nick. I also have another question: in the page.tpl.php file, where do I put the new php line

Currently, I have this in the body section (I commented out the theme ('links')... which is in the same section.

Not sure if this matters, but I am using the theme Garland.

Thanks.

7 months ago

Daniel,

Within your page.tpl.php file, you'll want to put the 'print $name_of_new_region' code wherever you want the navigation to show up.

Nick

5 months ago

Hi Nick, thanks for the article :)

I found a typo:

BAD
regions[name_of_new_region] = name of new region
GOOD
regions[name_of_theme] = name of new region

5 months ago

Niels,

Could you clarify what you mean? In the .info file, the value within the brackets after 'regions' should be the name of the variable you'll be referencing in your templates. This value should be the name of the region, not the theme.

Nick

zac
4 months ago

disreguard niels Bom's comment, he doesnt know what hes talking about. the author has it correct

Alex
4 months ago

Why is the function outputing always the primary links instead of the child nodes of current page?

4 months ago

Alex,

Not sure I understand your question – could you clarify?

Nick

2 months ago

Awesome article Nick. I've been searching for just how to do drop down menus in drupal with using a third party module, and this method finally solved that problem.

2 months ago

That should read *without using a third party module* my bad

2 weeks ago

This sounds neat, i can't figure out why primary links are not drop down by default.. Looks like lots people are trying to figure it out from all the results on a google search.
Is there some other method that will work? I have been messing with this for days with no success.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. Beside the tag style "<foo>" it is also possible to use "[foo]".

More information about formatting options