Building a Category Based Mega Menu in Expression Engine

Building a Category Based Mega Menu in Expression Engine

Andrew profile photo
Written by Andrew on 2nd September 2013

You don't need to look far these days to see mega-menus used on websites. They've become especially popular on ecommerce sites as we've seen a shift towards horizontal navigation systems where inevitably, space is at a premium.

Having been asked recently to update a navigation menu on one of our client sites, I though I'd summarise how we built a mega menu on an Expression Engine site using Structure and Structure Entries. Structure was already being used on the site and we didn't really want to change the current site structure, so by using categories and another add-on, Structure Entries, we were soon able to build out our menu, grouping each entry under a category heading.

The beauty of this approach is that the menu us fully dynamic. The downside, if there was one, is that the menu is ordered by having entries in a given category - and not through structure itself.

You'll need to have Stucture and Structure Entries installed on your EE build to follow this example.

Solid Foundations

This example focuses on the Expression Engine tags only. Good markup is assumed, but as there are numerous ways in which mega-menus can be styled, I'm not going to get involved in the CSS.

Our basic navigation menu markup looks like this.

<nav role="main">
 <ul class="top-level">
 <li><a href="/" title="Home" class="home"> </a></li>
 <li><a href="/our-products" title="Our Products" {if segment_1=="our-products"}class="active"{/if}>Our products</a>
 <ul class="products">
 <li>{Our mega menu content and tags will go here}</li>
 </ul>
 </li>
 <li>Other links</li>
 </ul>
</nav>

We're going to have a drop down menu under our Products heading which will show each product, within a category heading.

Getting the entries we need

Structure has plenty of navigation tags that give a variety of options for building up your navigaiton. However, there aren't any options for pulling out entries within a specific category so we can look to Structure Entries to lend us a helping hand.

Our EE setup has a products channel, with a category group attached to it, so we need to pull out the categories, and respective entries in the products channel.

We'll start by grabbing the categories we want.

{exp:channel:categories channel="products" style="linear" show_empty="no"}

The style="linear" parameter means EE won't add in its own nested html tags - we don't want these as we've already got our markup prepared. As this is a looping tag pair, it will loop through each category we have in the products channel, however, we don't want to show any categories with no products in them - hence we've included show_empty="no".

We'll use the {category_name} tag to get each category name, then we'll use Structure Entries to pull in the entries we need. Thankfully, we can nest the Structure Entries tag within our channel categories tag.

{exp:structure_entries category_id="{category_id}"}

This tag is basically calling all our entries in the current category, as it loops through the list. We can then pull out the {title} and {url_title} for each entry returned.

<a href="/our-products/{url_title}">{title}</a>

The full code

Creating this menu was actually surprisingly simple, with the full code looking like this.

<nav id="mainNav">
<div class="width">
 <ul class="top-level">
 <li><a href="/" title="Home" class="home"> </a></li>
 <li>
 <a href="/our-products" title="Our Products" {if segment_1=="our-products"}class="active"{/if}>Our products</a>
 <ul class="products">
 <li>
 {exp:channel:categories channel="products" style="linear" show_empty="no"}
 <div class="family-group">
 <h2>{category_name}</h2>
 {exp:structure_entries category_id="{category_id}"}
 <p>
 <a href="/our-products/{url_title}">{title}</a>
 </p>
 {/exp:structure_entries}
 </div>
 {/exp:channel:categories} 
 </li>
 </ul>
 </li>

The final menu on the front end looks like this.

Mega Menu Example

Adding products into the respective categories is easily done thorugh the channel entries, and each product could of course belong to multiple categories if you wanted.

Services Discussed