Navigation


Breadcrumbs

A howto guide: Replacing a top menu/nav bar with a Suckerfish menu in Drupal

It's a sucker fish! What else would it be?

When I picked this template I sat out to heavily modify it to my specifications.
I'm new to Drupal theming, so I've just scratched the surface so far, changing the CSS to the colors I want, and redoing the images. But now I'm delving into something a bit more challenging: turning my top menu bar into a Suckerfish-style menu.
Since the way I've always learned how to do this is by pulling apart other people's code, I started with other themes that had Suckerfish-style menus. I first ran across Newsflash by RoopleTheme, but they went a little more advanced than I wanted to go...there's has a button to enable the Suckerfish menus through the Theme Setting API, and a Suckerfish-specific region near the top. I didn't want any of that as the only person using this theme is myself. I just wanted to change my top-nav bar, so I looked around some more and found this simple theme based on Garland. It seemed to do exactly what I wanted, so I downloaded it started looking at the page.tpl.php file for my theme (that's the template that renders the actual pages) while inspecting my main page using the excellent X-Ray tool in CSSEdit by MacRabbit (small plug: it's the most capable and full-featured CSS editor for Mac I've run across, and it has almost no learning curve...it beats the pants off of both StyleMaster and Coda). discovered that the top menu bar on my page was rendered with the code:

<ul id="nav">  
  <?php if (isset($secondary_links)) { ?>
<?php print theme('secondary_links', $secondary_links, array('class' =>'links', 'id' => 'subnavlist')) ?>
<?php } ?>
   </ul>
   

Next I looked through the code of the page.tpl.php of the theme based on Garland with the suckerfish menus, and looked for where it rendered it's primary links. That was done in a very similar section using the code

    <div id="nav">
<?php print theme('menu_tree',variable_get('menu_primary_menu',0)); ?>
</div>
   

This code obviously prints out the menu_primary_menu as a menu_tree, which is what you need for a Suckerfish menu (in all the implementations I've seen). So I simply changed everything from <ul id="nav"> to </ul> like so:

<ul id="nav">  
     <?php print theme('menu_tree',variable_get('menu_secondary_menu',0)); ?>
</ul>
       

This replaces my top menu bar with a menu tree. That was the first step in this project. You need to do this on any page*.tpl.php files you may have to keep the menu bar consistent throughout the site (I have a page-front.tpl.php in addition to page.tpl.php).

Next we're going to edit the page.tpl.php, and in the header section, right under where the template inserts the scripts (it's at the top of the file..should be obvious where) we are going to insert the following code:

 <script type="text/javascript"><!--//--><![CDATA[//><!--

sfHover = function() {
        var sfEls = document.getElementById("nav").getElementsByTagName("LI");
        for (var i=0; i<sfEls.length; i++) {
                sfEls[i].onmouseover=function() {
                        this.className+=" sfhover";
                }
                sfEls[i].onmouseout=function() {
                        this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
                }
        }
}
if (window.attachEvent) window.attachEvent("onload", sfHover);

//--><!]]></script>

That's the IE hack to make it work under Internet Explorer. I also could have used an external JavaScript file and a drupal_add_js() in the template.php, which would have been more elegant, but I decided since I'm the only one using it I might as well just slap it in the template file. Also I believe having the code in the page.tpl.php reduces the overhead of downloading an external JavaScript file, since the script is so small.

Finally, I had to edit the CSS. The theme I originally downloaded had a separate menu.css, so I'll post that code so you don't have to see how I've modified it to be specific to this site. You can either add this code to your style.css, or add it to a separate CSS file using drupal_add_css in the template.php. Be sure to replace any existing #nav ids with these. To keep the style of your current theme you may want to go through each one and only add the appropriate lines.

#nav {
position: absolute;
top: 20px;
  }
 
#nav a {
  font-style: normal;
  font-size: 11px;
  font-family: Tahoma;
}

#nav, #nav ul {
        float: left;
        list-style: none;
        line-height: 22px;
        height: 22px;
        font-weight: bold;
        padding: 0 5px 0;
        margin: 0 0 0 0px;
}

/* top level links */
#nav a {
        display: block;
        line-height: 22px !important;
        line-height: 20px;
        height: 22px;
        background: none;
        color: #ffffff;
        font-weight: bold;
        text-decoration: none;
        padding: 0 1em;
        border-bottom: 0px;

}

/* sub level links */

#nav ul ul  a {
        display: block;
        color: #ffffff;
        font-weight: bold;
        text-decoration: none;
        padding: 0em 1em;
}


/* parent level menu */

#nav a.daddy {
   background: url(images/blog_menu_arrow.png) center right no-repeat;
}

/* top level buttons */

#nav li {
        float: left;
        padding: 0;
  background: none;
  width: auto;
}

#nav li ul {
        position: absolute;
        left: -999em;
        height: auto;
        width: 15em;
        font-weight: normal;
        border-width: 0;
        margin: 0;
        padding: 0

        }

#nav li li {
        float: left;
        padding: 0;
        width: 15em;
        background: url(images/blog_menuitem_bg.png) repeat-y;
}


/* margin for pullouts */
#nav li ul ul {
        margin: -22px 0 0 15em;
}




#nav li:hover ul ul, #nav li:hover ul ul ul, #nav li.sfhover ul ul, #nav li.sfhover ul ul ul {
        left: -999em;


}

#nav li:hover ul, #nav li li:hover ul, #nav li li li:hover ul, #nav li.sfhover ul, #nav li li.sfhover

ul, #nav li li li.sfhover ul {
           left: auto;
    background: #818181;
        }

#nav li:hover, #nav li.sfhover {
      left: auto;
      background: #4971BA;

}

#nav li:hover a, #nav li.sfhover a {
    color: #ffffff;

}

#nav li li:hover a, #nav li li.sfhover a {
    color: #ffffff;

}

Now you can customize the style of the menu to your heart's content.

Now remember, there are three places you need to insert code: the menu_tree renderer in your page.tmp.php, the JavaScript in your template.php, and the CSS in your style.css.

You should now have a Suckerfish menu in your top menu bar.

Note a few things: in this implementation I have turned my "Secondary links" menu into the Suckerfish menu. You can change that if you want. Also, these codes are specific to my theme, but you can modify them as you wish.

And if you have any questions, or if this isn't working for you, please ask in the comments. Thanks!

Trackback URL for this post:

http://circlesandscissors.com/trackback/226

Recent trackbacks

Navigation