How to add a Category-based Mega Menu in Wordpress Without a Plugin

Mega Menu is a content-rich menu where each category (or menu item) shows items (or child list) of that category either as a text list or image & text list. Look at the image for this post. On the main navigation menu, you will see menu list items: Level 1, Fitness, Mind, Body, etc. The first item there is a "normal" list item (a link to a page) while the rest are categories in Wordpress.
  • Disclaimer: I won't help you with the styling though via style.css or jquery. Proceed at your own risk.
If you look at my main menu here in Zirev.com, you'll see a toggleable menu item that goes by the name of topics. If you toggle that, you'll see different toggleable lists of recent posts according to labels. We'll do something similar to that except that the menu items (or first-level child menu-items) are categories and each of them contains a child list of recent posts on their own in Wordpress.

Basically, what we're going to do is create a mega menu based on recent posts by Category. So let's begin:

We're going to edit the walker class function so add this code on your navigation menu in header.php (or edit your code for wp_nav_menu):

<?php
$walker = new description_walker;
wp_nav_menu( array( 'theme_location' => 'primary', 'menu_id' => 'primary-menu', 'walker' => $walker ) );
?>

The new code should look similar to this:

You can change the array items according to your liking (e.g. change theme_location to another instead of primary), just don't change walker.

Add category menu items on your primary menu via your Wordpress dashboard

Refresh your website (homepage) and see if your menu is showing new category items.

Hover and inspect element of a category menu-item.

My hovered li menu-item has this:
class="menu-item menu-item-type-taxonomy menu-item-object-category"

Go to a post or a single page that belongs to a category featured on your menu. Inspect element of that category menu-item.

My li menu-item now has this:
class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor current-menu-parent current-post-parent"

Whatever your results, we are going to need that later

In your functions.php file, add this walker function:

class description_walker extends Walker_Nav_Menu {
    function start_el(&$output, $item, $depth, $args) {
        global $wp_query;

        $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
        $class_names = $value = '';

        $classes = empty( $item->classes ) ? array() : (array) $item->classes;

        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) );
        $class_names = ' class="'. esc_attr( $class_names ) . '"';

        $output .= $indent . '<li id="menu-item-'. $item->ID . '"' . $value . $class_names .'>';
        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $attributes .= ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
        $attributes .= ' class= "main-link"';


        $prepend = '';
        $append = '';
        $description  = '';

        $item_output = $args->before;
        $item_output .= '<a '. $attributes .'>';
        $item_output .= $args->link_before .$prepend.apply_filters( 'the_title', $item->title, $item->ID ).$append;
        $item_output .= $description.$args->link_after;
        $item_output .= '</a>';

        if ($class_names == ' class="menu-item menu-item-type-taxonomy menu-item-object-category"' or $class_names == ' class="menu-item menu-item-type-taxonomy menu-item-object-category current-post-ancestor current-menu-parent current-post-parent"') {
            ob_start(); ?>
            <ul class="cat-sub-menu">
<?php $the_query = new WP_Query( array( 'category_name' => $item->title, 'posts_per_page' => 5 ) );
if ( $the_query->have_posts() ) {
while ( $the_query->have_posts() ) {
$the_query->the_post();
if ( has_post_thumbnail() ) { ?>
<li><a href="<?php the_permalink(); ?>" class="cat-sub" rel="bookmark"><div class="thumbnail"><?php the_post_thumbnail(); ?></div><div class="cat-title"><?php the_title(); ?></div></a></li>
<?php } else { // if no featured image is found ?>
<li><a href="<?php the_permalink(); ?>" class="cat-sub" rel="bookmark"><div class="thumbnail"></div><div class="cat-title"><?php the_title(); ?></div></a></li>
<?php
}
}
}
wp_reset_postdata(); ?>
   </ul> <?php
            $item_output .= ob_get_contents();
            ob_end_clean();
        }

        $item_output .= $args->after;
        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}

Now, pay close attention to this code from above:

In the first line from the picture directly above, replace the class names generated from your results from instructions 4 and 5 in if($class_names ==

Basically, what you're going to do is to replace the content with your result from Step 4 the first occurrence of $class_names == which is highlighted in lime from Step 6 and then put the result from Step 5 on the next (the next occurrence of  $class_names == after "or") which is highlighted in orange from Step 6.

Make sure to pay close attention to the space before class="menu-item


Style your Mega Menu through your style.css file

I cannot share my styling because it could be highly different from your template. All you have to know (as you can see from the above image) is that I assign the ul list a class of cat-sub-menu and its child list of class cat-sub.

If you want to show more than five posts in the mega menu, change via posts_per_page.

I have a live working website for this at healthdoll.com.

18 Comments

  1. Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging…

    web designing course in chennai

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. This comment has been removed by a blog administrator.

    ReplyDelete
  6. This comment has been removed by a blog administrator.

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete
  8. This comment has been removed by a blog administrator.

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
  10. This comment has been removed by a blog administrator.

    ReplyDelete
  11. This comment has been removed by a blog administrator.

    ReplyDelete
  12. This comment has been removed by a blog administrator.

    ReplyDelete
  13. This comment has been removed by a blog administrator.

    ReplyDelete
  14. I have read all the comments and suggestions posted by the visitors for this article are very fine,We will wait for your next article so only.Thanks! Ozzun Cheap Domain and hosting company

    ReplyDelete
  15. Great blog thanks for sharing The tone of every picture on your website, Instagram post and Facebook Ads counts more than you think. Having a simple digital marketing is not enough for your brand. You need a graphic designing company that creates a unique brand identity that matters. An idea that goes beyond just a product - a thought leader in the industry. How about you start a free demo with us right now at Adhuntt Media.
    digital marketing company in chennai

    ReplyDelete
  16. Nice blog thanks for sharing Growing your own plant comes with its own challenges and responsibilities. This is why you need a plant nursery in chennai who is ready to help you out throughout the way and guide you through the hurdles of growing a plant - Enter Karuna Nursery Gardens.
    plant nursery in chennai

    ReplyDelete
  17. Excellent blog thanks for sharing Buy the best beauty parlour products wholesale in Chennai at Pixies Beauty Shop. Thousands of global top-tier brands to choose from and friendly faces all over, we would love to make your Salon journey, one the world recognizes.
    Cosmetics Shop in Chennai

    ReplyDelete

Post a Comment


  • SHARES





More from Zirev