Creating a drop down navigation is an old technique by now but it’s still used in a lot of cases to hide parts of a navigation. In addition to the plain CSS menu I wrote more than 2 years ago, I decided to write a new tutorial which uses JavaScript as well. You might ask why: Avoiding JavaScript is nice but creating something as complex as a drop down navigation without any JavaScript leads to a few ugly work arounds. You’ll also have some difficulties to add a fade out and fade in effect unless you’re using CSS3 which isn’t well supported yet.
But at the end it’s up to you, both solutions can work just fine!
Using SooperFish is also a bit easier for us, you’ll see at the end of the tutorial how little code you needed.
At the end your navigation can look like this:
Prerequisite to create your drop down menu
It’s rather simple, the only thing you need is the jQuery drop down plugin called SooperFish. You can find a link to download it on this page: http://www.sooperthemes.com/open-source/jquery/jquery-sooperfish-dropdown-menus.
Once you’ve got the ZIP file, extract all the files into a folder of your choice, we’ll later use some (not all) files from it.
Creating a new block template
If you worked with concrete5 before you’ll probably know that you should never modify any files located in the “concrete” directory. It’s part of the CMS core which gets overwritten whenever you update to a newer version of concrete5. Luckily this isn’t necessary for lots of things! We can easily create an addon, or a block template in this case, without touching the core at all.
In the root of your website, open the folder called “blocks” and go though these steps:
- Create a folder called “autonav”
- Within “autonav”, create a folder called “templates”
- Within “templates”, create a folder called “sooperfish”
- In the last directory you created, “sooperfish”, create a file called “view.php” and put the following content in it:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php $bvt = new BlockViewTemplate($b); $bvt->setBlockCustomTemplate(false); function callback($buffer) { return (str_replace('class="nav"', 'class="sf-menu" id="nav"', $buffer)); } ob_start("callback"); include($bvt->getTemplate()); ob_end_flush(); ?> |
Background information about the autonav template view.php
What does this template do?
Since the HTML structure needed by SooperFish is almost identical with the default autonav template, we don’t copy the whole template which would create a lot of redundant information. Instead we include the default template in our new template. However, there are still a few things we modified. The original template has an element like this:
<div class="nav">but we want this:
<div class="sf-menu" id="nav">Having this element allows us to use the default CSS files shipped with the Sooperfish plugin. You could modify the CSS files as well and remove all the output buffering functions in the code above.
- Create another file in the same directory called “view.js” and put this content in it:
1 2 3 | $(document).ready(function() { $('.sf-menu').sooperfish(); }); |
- In the directory where you created “view.php” and “view.js”, create another directory called “js”
- From the SooperFish ZIP, copy “jquery.sooperfish.min.js” and “jquery.easing-sooper.js” into the “js” directory.
- On the same level as “js”, create another directory called “css”
- From the Sooperfish ZIP, copy “sooperfish.css” and “sooperfish-theme-black.css” into the directory called “css”
We’ve already created and copied all the files we need, the only thing we have to do is to make sure our new template is used. Your file structure should look like this now:

Go to your page and start editing the page and modify the autonav block to make these settings:
It’s important that you select “Display all” in both “Sub Pages To Display” and “Sub-Page Levels”. When you work with a JavaScript based navigation you usually print all the items into the HTML output, but hide some of them using JavaScript. Click on Update when you’re done and click on the block you modified again, but this time select “Custom Template” and select “Sooperfish” and click on “Update” again.
Publish the changes and you’ll see your new drop down navigation!


Remo Laubacher
It seems like the jQuery plugin site isn’t working well these days. You might want to try this page: http://phloor.13net.at/phloor_plugin/view/109/menu-sooperfish-for-18
Khalid
Thanks for this cool tutorial
Its possible to add an “images” folder in the css folder in order to show te arrows for some themes of the menu.
Also, you might choose any of the 4 different css preconfigured files. All that has to be done is putting the sooperfish.css and the sooperfish-theme-xxxx.css in the css folder.
Of course, it is also possible to change some features in the sooperfish.css.
Do you have any idea of how to tweak the behaviors of the javascript animations?
Cheers anyway and give us soon a Jquery “from scratch” Navbar menu tutorial.
Happy New year!
Remo Laubacher
I’m using a preconfigured file already, aren’t I?
good point about adding images in the css directory!
Remo Laubacher
Khalid, it seems like the documentation of Sooperfish is a bit messed about right now but try to check this page: http://www.sooperthemes.com/sites/default/files/SooperFish/example.html It uses the JavaScript available here (search for “animation” and “ease”): http://www.sooperthemes.com/sites/default/files/SooperFish/demosite.js
Maggie
Hi Remo,
Thanks very much for this tutorial. I’m running into one issue I’m hoping you might be able to help me with:
Everything works great if I embed an area in a Concrete5 template and then add the autonav block to it. However, I’d like to embed the block directly in my header template (without creating an area that the nav can be added to / removed from). When I do this, the dropdown effect stops working (also, though less importantly, the little downward-pointing arrow graphic normally displayed with each top-level menu item disappears). The CSS styling (background & border colors, font size, etc.) is still there.
I’m somewhat of a newbie to web development so there could be something simple I’m missing, but I’m having trouble figuring out a fix. Any pointers would be appreciated.
Maggie
Maggie
I meant to include the code I’m using to embed the block:
$autonav = BlockType::getByHandle(‘autonav’);
$autonav->controller->orderBy = ‘display_asc’;
$autonav->controller->displayPages = ‘top’;
$autonav->controller->displaySubPages = ‘all’;
$autonav->controller->displaySubPageLevels = ‘custom’;
$autonav->controller->divSubPageLevelsNum = ’1′;
$autonav->render(‘templates/sooperfish/view’);
Remo Laubacher
Hi Maggie,
I’m making some assumptions but this theory would work:
Every block or template in concrete5 can have one or several JavaScript / CSS files. Since these files should be included within the head tag of the document, concrete5 looks for them before the actual block content is rendered.
How does concrete5 look for these blocks? Since everything is database based, it searches for all blocks on the page to be rendered using an SQL query, which then adds the .js and .css files.
However, when you use the code above, which I partially described here: http://www.codeblog.ch/2009/04/concrete5-blocks-within-templates/, concrete5 doesn’t know what blocks will be on that page and can’t include the necessary .js and .css files.
What does this mean? I’d start by looking at all .css and .js files in your block (or template) and add them manually to your theme. As far as I know, there’s currently no way concrete5 could detect them and thus no way around that hard coded part in your theme.
Can you please try that? If it doesn’t work – a link to your website would be helpful!
Thanks
Maggie
Thanks for the quick reply, Remo!
Unfortunately, the site is in development and I don’t have it uploaded anywhere yet, but I’ll do my best to explain what I’m seeing.
I viewed the source for one of the pages in the site and it looks like the block’s JS & CSS files are getting included in the head section, so that seems ok. I thought maybe some other JS I inserted might be conflicting with that which Sooperfish depends on, so I stripped all of that out, but still no luck. Finally I did a diff of the HTML generated in each of the two cases (I probably should have started there), and noticed this:
When I use the code above to embed the autonav block directly in the template, the sub-pages aren’t printed in the list that’s generated. If I instead add an area to the template, then add the autonav block and configure the same settings via the UI, the sub-pages are printed.
Looking into this even further I found the problem seems to be with setting displaySubPageLevels = ‘custom’ (followed by divSubPageLevelsNum = ’1′, as I only want to display the top level-pages and one level below). As I mentioned, this works fine when I use the UI to add the block to an area and configure these settings, but doesn’t work when I embed it directly (setting displaySubPageLevels = ‘all’ in the code does work). Puzzling, because ‘custom’ seems to be the same value set via the UI…
Maggie
fastcrash
remo, i love you!
Aldebahran
Hello
Thanks, this was very helpful. However I’m new to website design and my menu doesn’t have the size I want…
?
Can you help ? I want to have the menu width to be 100% and all the main menu items to be equal size. How can I do that (with a sooperfish for dummies style please
Remo Laubacher
I’m sorry but I’m currently caught up in a huge project and don’t have any concrete5 playgrounds nor the time to create a complete solution for you!
Tom
Doesnt work on as described on v5.5.
Waste of time, I’ll have to buy the add-on as I dont have more time to waste.
Remo Laubacher
This tutorial has been written using v5.5, I just tested it again and it works fine but please go ahead and buy the commercial add-on! I don’t mind not to have such nice people on my blog who post such really nice comments to motivate me to write and publish more fresh stuff.
Matt
Thanks Remo….you rock!
Jason Mixon
Thanks for the tutorial, very helpful and it worked great in v5.5. Keep up the good work!
Sam
Wow, awesome. Exactly what I was looking for. Worked perfect for me!
Remo Laubacher
Thanks, good to know there are some people who managed to get this working!