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, 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):

$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() ) {
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>
wp_reset_postdata(); ?>
   </ul> <?php
            $item_output .= ob_get_contents();

        $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


  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

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

  3. This comment has been removed by the author.

  4. This comment has been removed by the author.

  5. great customer service is meeting the hopes of the customers so much as they are interested in being served. Most of the businesses and corporations characterizes customer service as delivering the appropriate amount of service to the customers that they're searching for throughout your interaction together. You engage what they're desiring, what they're looking, and also you satisfy those needs. You Are Able to visit
    in the event that you are interested in figuring out more on this topic in a whole lot more thickness.

  6. Thanks for the blog loaded with so many information. Stopping by your blog helped me to get what I was looking for. make a website

  7. With so many WordPress donation plugins out there, it can be hard to know which one is right for you. I strongly recommend Donorbox, because it's easy to use and works perfectly.

  8. You're on your way to starting your very own WordPress Website. Fun times! Go ahead and unzip the contents of your WordPress ZIP (the one you downloaded from the website), and begin uploading the files through an FTP software (your host can help you with that).wordpress expert help

  9. This is very educational content and written well for a change. It's nice to see that some people still understand how to write a quality post! A2 Hosting review


Post a Comment


More from Zirev