Suckerfish Style Menus in Drupal 6.x
I spent hours and hours hunting around for a simple solution to implementing suckerfish-style drop-down menus in Drupal 6. Lo-and-behold, I couldn't find one. Every solution out there was overly complicated, and didn't quite do what I wanted it to.
After a few hours of hacking around, this is the solution I came up with.
First I started up by setting up my menu structure. I went to Administer >> Site building >> Menus >> Primary Links, and set up my menu, setting up all the appropriate pages and their sub-pages directly beneath them. That was the easy part. Now for the rest...
First I setup my 'suckerfish' functions. I found a script online that emulated suckerfish style behavior using jquery. Since jquery is already built in to Drupal, this was easy enough to implement.
dfn_menus.js
/* Emulates Suckerfish-style functionality with JQuery */ /* Adds animation effect for drop-down and fadeups */ $(document).ready(function(){ $("#dfnmenu li").hover( function(){ $("ul", this).fadeIn("fast"); }, function(){ $("ul", this).fadeOut("fast"); } ); if (document.all) { $("#dfnmenu li").hoverClass ("sfHover"); } }); $.fn.hoverClass = function(c) { return this.each(function(){ $(this).hover( function() { $(this).addClass(c); }, function() { $(this).removeClass(c); } ); }); };
Once thats done and saved, we also need to create a style sheet. I'll paste mine here as a reference. You may want to change it to suit your preferences. Disclaimer: I chopped it up and removed bits that were not needed, since they applied to the theme and skin that I had applied. I may or may not have left remnants and/or removed something I shouldn't have.
dfn_menus.css
/* Navigation */ .menu ul, .menu ul li ul { list-style: none; margin: 0; padding: 0; } .menu { z-index: 10; position: relative; text-align: left; width: 800px; height: 33px; } /* TOP LEVEL MENU ITEM */ .menu ul li { float: left; margin: 0; padding: 0; position: relative; } /* TOP LEVEL MENU ITEM */ .menu ul li a, .menu ul li a:link, .menu ul li a:active, .menu ul li a:visited { font: 1.1em/27px Verdana; color: #555555; display: block; padding: 1px 34px 0px 34px; margin-top: 1px; text-decoration: none; border-left: 1px solid #ddd; outline: none; } /* Make sure the first item in the list doesnt have a left border */ .menu ul li.first a { border-left: 0px; outline: none; } /* TOP LEVEL MENUS ITEMS ON HOVER */ .menu ul li:hover a, .menu ul li.sfHover a .menu ul li a:hover { background-color: red; background-position: -15px -33px; height: 30px; outline: none; } /* SECOND LEVEL MENU ITEM */ .menu ul li:hover ul li a, .menu ul li:hover ul li a:visited, .menu ul li.sfHover ul li a, .menu ul li.sfHover ul li a:visited { font-weight: normal; color: #666666; background:#e8f0f3; margin: 0px; border: 0px; outline: none; height: 23px; padding: 0px 34px 3px 34px; } /* SECOND LEVEL MENU ITEM HOVER */ .menu ul li:hover ul li a:hover, .menu ul li:hover ul li.first a:hover .menu ul li:hover ul li.last a:hover .menu ul li.sfHover ul li a:hover .menu ul li.sfHover ul li.first a:hover .menu ul li.sfHover ul li.last a:hover { height: 23px; background: #FFFFFF; padding: 0px 34px 3px 34px; color: #000; width: auto; } /* SECOND LEVEL MENU ITEM */ .menu ul li ul { width: 200px; /* expand as needed for longer submenu names */ color: #000000; list-style: none; margin: 0px; padding: 0px; position: absolute; top: -999em; left: 0px; border: 1px solid #dddddd; /* border around dropdown menu */ opacity: 0.9; -moz-opacity: 0.9; } .menu ul li:hover ul, .menu ul li.sfHover ul { top: 30px; } .menu ul li ul li { border: 0px; float: none; padding: 0px; margin: 0px; color: #000000; } .menu ul li ul li a { border: 0px; white-space: nowrap; float: none; padding: 1px 34px 1px 15px; margin: 0px; display: block; height: 29px; color: #000000; } .menu ul li ul li a:visited { color: #000000; } .menu ul li ul li a:hover { background: #CEFFCE; color: #000; border: 0px; margin: 0px; }
Once you have both of those files saved into place, now its time to make the magic happen. Now navigate to your theme folder, wherever it might be (usually something like /sites/all/themes/) and open your page.tpl.php file. This is where we make our changes.
First we include our css and js files. Add the following somewhere in the head section:
page.tpl.php
<!-- DFN Menu Library + CSS for drop-down --> <script src="/sites/all/libs/dfn/dfn_menus.js" language="javascript" type="text/javascript"></script> <link rel="stylesheet" type="text/css" media="screen" href="/sites/all/libs/dfn/dfn_menus.css" />
Once that's done, we actually have to make the menu print out. This is the way I did it. I commented out the line that prints the $primary_links variable, and replaced it with this:
page.tpl.php
<div id="dfnmenu" class="menu"> <? $my_menu = menu_tree('primary-links'); $my_menu = str_replace("leaf", "", $my_menu ); $my_menu = str_replace("active-trail", "", $my_menu ); $my_menu = str_replace("menu", "", $my_menu ); $my_menu = str_replace("active", "", $my_menu ); $my_menu = str_replace("expanded", "", $my_menu ); $my_menu = str_replace(" class=\"\"", "", $my_menu ); print $my_menu; ?> <div style="clear: both;"></div> </div>
What this does is loads the menu tree, and then strips out all the extra stuff I didn't need, liks classes and id's and the like - I just wanted the nested unordered lists. Once that's done, it prints out the results. And that's it. Simple right?
This may and most likely will require lots of css tweaking on your part. But its a solution that has worked for me, and hopefully will lead you in the right direction! Tested with Firefox 2+ and IE7. May or may not work well with older browsers.
Happy Coding!
~ digifuzz
Posted on Friday, June 13th, 2008 at 10:11 am and is filed under Drupal, Javascript, Php. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
June 23rd, 2008 at 4:26 am
Thanks, digifuzz for this coding help. Works great in IE and FF but won’t show at all in Opera. Is there a fix or hack for Opera?
June 23rd, 2008 at 5:16 pm
Hey Linda, I didn’t test it on Opera, but after some quick googling, I read that suckerfish style menus in opera are a bit quirky, specially if you don’t set a specific width to the li’s. So just for kicks, try applying a “width: 150px;” or whatever suits you better to the top-level li’s.
/* TOP LEVEL MENU ITEM */
.menu ul li {
float: left;
margin: 0;
padding: 0;
position: relative;
width: 150px;
}
I’ll do a little testing soon and let you know what I come up with.
~ digifuzz.
June 24th, 2008 at 5:37 am
Tried a width change and clear: both. Nothing changed. I’m considering changing to another CMS. Unfortunately.
June 24th, 2008 at 8:11 pm
Hmm, strange. I tested it in Opera, and - besides being placed a few pixels below where it displays on the other browsers - it seems to work fine. If you haven’t already completely ditched Drupal, could you explain exactly what does happen in your browser?
~ digi
July 20th, 2008 at 9:57 am
I got this working perfectly with some quick CSS tweaking, but my question i’m stumped on.. it makes my Primary Links work beautifully but then when logged in as Admin my navigation links in my left blocks go all messed up and wreck the page.
How can I make this ONLY implement for the Primary Links and ignore all other menus?
Cheers.. thanks for putting this out there, been messing with it for a few weeks now and I finally feel like i’m nearly there!
July 22nd, 2008 at 8:07 pm
Hey, nice work!
I’m having a little difficulty implementing it with the Zen theme though. I notice in the js code you refer to #dfn css styles which are not (no longer) in your css file.
Did you take those out when you were editing?
Also i saved my js and css files into my subtheme folder and just added the following code to the top of the template.php:
drupal_add_js(path_to_theme().’/myMenus.js’, ‘theme’);
and this to the .info file:
stylesheets[all][] = myMenus.css
I believe this is better for using with a subtheme? I’m new to Drupal =P
Have you tried decoding whatever Roople Themes is doing with their templates? Maybe i should just get one of their themes and edit it.
I can’t believe that there isn’t a suckerfish drupal module…
Thanks
July 22nd, 2008 at 8:12 pm
Bah, my bad, i see it where you put it in the page.tpl.php coding.
Could you maybe clarify where exactly that should go?
This is what i’ve got:
I must have not entered it correctly.
Thanks again!
August 4th, 2008 at 9:04 am
Hi diggifuzz,
Thx for sharing your code,
I have seen that the roople themes use a version of suckerfish:
http://demo.roopletheme.com/
August 6th, 2008 at 10:36 am
Ya i ended up modding a the litejazz roople theme to get my suckerfish menus to work.
August 8th, 2008 at 4:54 pm
Sorry I haven’t answered any of your questions as of late. Family has been demanding my time tons, which is not a bad thing, as far as I’m concerned.
@sen: Wrap your primary_links in a div with a unique class, and change your suckerfish related css to apply to only elements within that div.
@Suckfish & Nico: I have actually looked at the roople themes in the past (specifically the tapestry theme), and while it had the desired end-results, it required more region and block creating and I decided I wanted to try to use suckerfish without having to do all that. Call it a personal challenge, etc. It’s always fun to see how many different paths one can take to reach the same happy ending.
August 26th, 2008 at 4:40 am
I have been using a module called nice_menu’s in Drupal, but for some reason I can’t get the drop downs working in IE6. FF / Safari / Opera are no problem.
Seems like the JS isn’t working.
I’m wondering though, why can’t drupal just output menu’s as nested ul, li’s?
It seems you need major work-arounds just to get this to work.
August 26th, 2008 at 5:09 pm
Yeah, I don’t know. The simplest way I could get Drupal to output the lists as nested ul/li’s is as shown above in the page.tpl.php section. If there is a simpler way, I’d love to hear about it.
~ digifuzz