Creating context sensitive primary/secondary menus

Description
A new feature created by Richard Archer for 4.7 allows you to link the primary and secondary menus in a way that makes them context sensitive. A working example of context sensitive menus is available at http://www.massaflcio.org.

The links on the left are actually the primary menu. When you click the link at the top, "Massachusetts AFL-CIO" notice a second menu is show across the top of the page. This top menu is the secondary menu. Notice that the "Massachusetts AFL-CIO" button is highlighted, and the "Who we are" item in the secondary menu is also highlighted. If you click on the various secondary menu items, you'll notice the primary button remains lit. Also notice that if you click on "Staff" and then view a staff member by clicking on their title, both the primary and secondary menu items remain highlighted.

How to pull this off
While changes to the code were taken in 4.7 to make this feature possible, it still takes quite a bit of work to get working properly. Hopefully, the necessary changes to the Drupal core will be made in the near future to make this feature much easier to implement.

Step 1: Change menu settings
Go to the administer -> settings -> menus page. Set "menu containing primary links" to "Primary links". Also set "Menu containing secondary links to "Primary Links". Save the configuration.

Step 2: Create your navigation hierarchy
Go to the administer -> menus page. Create some menu items in the primary menu. For each of those menu items, create some children. The children menu items will act as you secondary menu. The parent menu items are your primary items.

...

See Menu Block Split module, Menu Trim or Sliced menu.

  • Sliced menu takes your main site menu tree and provides individual blocks for the primary sections that you can then place yourself using block visibility. It's pretty basic functionality.
  • Menu Block Split provides a single block for your main menu tree that shows only the current 'branch', limited to a certain height. This block only has to be placed once, and will display different content depending on context.
  • Menu Trim provides a per-menu-item setting that makes any menu level available as an independant block. You then have to place it yourself. This is more configurable, but therefore requires more admin to maintain.

I wanted to add my 2cents in

jimmygoon - January 14, 2007 - 18:21

I wanted to add my 2cents in case someone finds them selves looking at this article and wondering what it means. This article did not work for me but that could be because it says work in progress - either way here is how I got my solution working.

I have a district website and I need to broken down in 6 sections... each with its own menu. I did this using custom paths and url aliases as well as some maneuvering on the blocks page. For example lets say I want to construct the menu for school-a. I would create paths, arbitrarily, for school-a/menus/lunch, school-a/menus/breakfast, etc just creating whatever structure I like. After creating those menus, I simply go to the block page and tell it to only show the menu on "school-a*" (that is what I put it the text box) so that any time you are on a page who's URL begins with school-a* it will show the menu.

Then just create primary links to each "section" of your site and waalaa! Hope this helps someone!

url/path alias misdetects

bcswebstudio - May 2, 2007 - 20:31

In implementing my secondary menus with block-visibility based on paths as suggested by jimmygoon, I thought it would be easy to have a single contact page simply "url aliased" like this:
system path: contact
alias: meetings/contact
alias: weddings/contact
alias: banquets/contact
etc.
so it still fits with the "subpages" or secondary menu's theme.

After a little finagling, it seems to work! First, I had a strange duplication of "contact" in the Meetings menu, then I saw that sometimes meetings/contact actually went to banquets/contact, but not consistently.. Finally, sitewide contact (/contact) even now still shows the Meetings secondary menu for some reason.. Though I'd prefer not to, I may try making a unique contact alias like "contact-us".

Also, I've added "section root" page url-aliased as "meetings" and "weddings" etc. which will act both as a landing page from the main menu as well as catching that "up a level" browsing many websites neglect to handle (when visiting mysite.com/meetings/contact, google toolbar (or direct URL manip) lets you "go up a directory" to mysite.com/meetings). Unfortunately, without the trailing slash, I can't, then, simply relative link to "contact" in hopes that it will link /meetings/contact. C'est la vi!

Hmm.. this is odd: my crafty

bcswebstudio - May 4, 2007 - 18:59

Hmm.. this is odd: my crafty /banquets/contact, /weddings/contact scheme works only when I'm logged in. An anonymous user always sees "/meetings/contact" regardless of the current path.

I tried [temporarily] enabling both path module accesses for anonymous to no avail...

Any other ideas?

More info: In admin>>menus, the "contact" paths all say "public-events/contact"... curiouser and curiouser

ah ha! contact list module and url path alias

bcswebstudio - May 4, 2007 - 21:12

Where there's a will, there's a way. I added the Contact List module which allows separate contact forms at paths like "contact/meetings" "contact/weddings". Then I url-aliased just the opposite for what I wanted:
meetings/contact => contact/meetings
weddings/contact => contact/weddings
public-events/contact => contact/public-events

Together with path-based block visibility, the menus work as desired.

--
..happiness is point and click..

How I did this...

swill - May 8, 2007 - 20:11

(NOTE: I am using Drupal 5x)
When I was building a new theme I wanted to have my primary links be tabs across the top and then when they were selected and had sub items then there would be tabs below as the secondary menu. I wanted to the primary tab to stay highlighted if the secondary tabs were selected so you could see what section you were in.

I did this through CSS which may not be ideal for all of you, but it is a valid solution, so I figured I would let you all know what I did...

when a secondary menu item is selected you have the following structure (for the most part) (check firebug in firefox):

<div id="primary">
  <ul class="links-menu">
    <li><!-- link info --></li>
    <li class="active"><a href="/?q=node/1"></a></li>
    <li><!-- link info --></li>
  </ul>
</div>
<!-- maybe some code here -->
<div id="secondary">
  <ul class="links-menu">
    <li><!-- link info --></li>
    <li><!-- link info --></li>
    <li class="active">
      <a class="active" href="/?q=node/4">biography</a>
    </li>
  </ul>
</div>

Knowing that you are going to have this structure, then you can use that fact in your CSS. Lets assume that you highlight your active tab in the primary menu with the following css: (for me this code is in the file style.css)

#primary ul li a.active { /*selected tab effect*/
  background-color:#164A83;
  color:#fff;
  text-decoration:none;
  cursor:default;
}

You can simply say that you want to use this same highlight if the secondary menu for this menu is selected as well. You can do it by changing the above CSS to:


#primary ul li a.active, #primary ul li.active a { /*selected tab effect*/
background-color:#164A83;
color:#fff;
text-decoration:none;
cursor:default;
}

This will make sure that your primary menu item is highlighted when any of its secondary menus are selected...

Hope this helps someone...

 
 

Drupal is a registered trademark of Dries Buytaert.