how to create a menu with all sub categories?

Is it possible to create a menu with a category such that each time that I had a sub category that automatically display on the menu?

As far as I know, if I have a menu with the category “fruit”, and I create the subcategory “bananas”, I have to manually add it.

Related posts

8 comments

  1. This depends on what kind of menu you are talking about:

    1)

    If you are talking about “custom menus” (found in the Backend under Design -> Menus) you can do the following:

    • Create a new function with the action hook add_category

    • inside of this function, you can create a new post of type the menu
      item type, which is added correctly to your menu

    • whenever a new category is published the menu item is added now

    • you should also hook into delete category, to keep your menu
      up-to-date

    2)

    You could do much easier without a wordpress menu:

    • just write a function to list your categories (or use the predefined
      wp_list_categories function)
    • if this is not sufficient write a customized one which (maybe
      recursivley) reads your categories from the database

    For option 1 to code you require some knowledge about WordPress though.

  2. I prefer using wp_list_categories. Here is my code I used in my last project:

    <?php wp_list_categories('orderby=ID&exclude=3,10,1,16,38&title_li=<span class="sidebar_heading d_shadow">' . __('Categories') . '</span>'); ?>
    

    You will get a list of all your categories and sub-categories.

  3. After many research I found a trustful useful solution, this class works well:

    class EntexAutoSubmenu {
    
        /**
         * Constructor
         */
        function __construct(){
            add_action('created_category', array($this, 'on_publish_category'));
        }
    
        /**
         * When publishing a new child category, add it to the appropriate custom menu.
         */
        function on_publish_category($cat_id){
    
            // Theme supports custom menus?
            if (!current_theme_supports('menus')) return;
    
            // Published taxonomy has parent?
            $cat = get_category($cat_id);
            if (!$cat->category_parent) return;
    
            $all_menus = get_terms('nav_menu', array('hide_empty' => true));
    
            // Loop through the menus to find page parent
            foreach ($all_menus as $menu) {
    
                $menu_parent = NULL;
                $menu_items = wp_get_nav_menu_items($menu->term_id, array('post_status' => 'publish,draft'));
    
                if (!is_array($menu_items)) continue;
    
                foreach ($menu_items as $menu_item){
                    // Item already in menu?
                    if ($menu_item->object_id == $cat_id) continue 2;
                    if ($menu_item->object_id == $cat->category_parent) $menu_parent = $menu_item;
                }
    
                // Add new item
                if ($menu_parent) {
                    wp_update_nav_menu_item($menu->term_id, 0, array(
                        'menu-item-object-id' => $cat_id,
                        'menu-item-object' => $cat->taxonomy,
                        'menu-item-parent-id' => $menu_parent->ID,
                        'menu-item-type' => 'taxonomy',
                        'menu-item-status' => 'publish'
                    ));
                }
            }
        }
    }
    
    $auto_submenu = new EntexAutoSubmenu();
    
  4. To solve this problem i tried to create a plugin which automatically create menu item for publish category under it’s parent category if in menu.

    Idea for plugin:

    1.in code, i used “created_$taxonomy” action hook.

    2.collect all the menu item ( by using wp_get_nav_menu_items)

    3.and put condition if parent of publish category lies in menu-item than a menu-item created as sub menu of it’s parent category.(by using wp_update_nav_menu_item)

    <?php
    /*
    Plugin Name: Auto Category Submenu
    Plugin URI: 
    Description: Create menu item when category publish/create if it's parent category in menu item.
    Version: 0.1
    Author: Mayank Gupta/Ravinder Kumar
    Author URI: 
    License: GPL2
    */
    
    class AutoSubmenu {
    
        /**
         * Constructor
         */
        function __construct() {
            add_action( 'created_category', array( &$this, 'on_publish_cat' ) );
        }
    
        /**
         * When publishing a new child page, add it to the appropriate custom menu.
         */
        function on_publish_cat( $cat_id ) {
            $cat = get_category( $cat_id );
    
            //menu id for you menus in which your sub-category's parent category as menu item 
            $menu_ids = array(101,100);
    
            //retrieve all meu items from menu
            foreach($menu_ids as $menu_id){
                $menu_items[] = wp_get_nav_menu_items( $menu_id, array('post_status' => 'publish','post_type' => 'nav_menu_item','output' => ARRAY_A, ) );
            }
            foreach($menu_items as $menu_item){
                $counter = 0 ;
                echo'<!--';
                print_r($menu_item);
                echo'-->';
                foreach($menu_item as $menu_term){
                    $menu_terms_id[] = $menu_term->object_id; //all menu items id
                }
            }
            //print_r($menu_terms_id); //test for items in menu
            foreach( $menu_terms_id as $menu_term ){
                if( $cat->category_parent == $menu_term){
                    wp_update_nav_menu_item( $cat_id, 0, array(
                    'menu-item-object-id' => $cat_id,
                    'menu-item-object' => $cat->taxonomy,
                    'menu-item-parent-id' => $menu_term,
                    'menu-item-type' => 'category',
                    'menu-item-status' => 'publish'
                ) );
                }else{
                    return;
                }
            }
        }
    
    }
    $auto_submenu = new AutoSubmenu();
    

    Note: plugin giving error (header already sent) and menu item not created when category publish.This may be another topic for problem but i put it here because this may be a solution if some suggest me where i am wrong.Sorry if i’m doing something wrong by putting it here

  5. I coded my own for one my of clients

    <div class="menu">
      <ul id="MenuBar1" class="MenuBarHorizontal">
        <li><a <?PHP if( count($_GET) == 0 ){ echo 'class="-current"';} ?> href="<?php echo esc_url( home_url( '/' ) ); ?>">home</a></li>
        <?php
            $category_ids = get_all_category_ids();
            sort($category_ids);
            foreach($category_ids as $cat_id) {
                $cat_name = get_cat_name($cat_id);
    
                echo '<li><a href="' . get_category_link( $cat_id ) . '">' . $cat_name . '</a>';            
                $args = array( 'numberposts' => -1, 'offset'=> 0, 'cat' => $cat_id, 'orderby' => 'ID', 'order' => 'ASCE' );     
    
                echo '<ul>';
    
                /* The 2nd Query (without global var) */
                $query2 = new WP_Query( $args );
                // The 2nd Loop
                while( $query2->have_posts() ):
                    $query2->next_post();
                    echo '<li><a href="' . get_permalink( $query2->post->ID ) . '">' . get_the_title( $query2->post->ID ) . '</a></li>';
                endwhile;
    
                // Restore original Query & Post Data
                wp_reset_query();
                wp_reset_postdata();
                echo '</ul>';
            echo '</li>';
            }
        ?>
      </ul>
    </div>
    
  6. i am using to show all category and sub category of category as a menu in my project.

    $all_categories = get_categories( $args );
    echo "<div class='container'>";
     echo "<div class='productsubmenu'>";
    echo "<ul>";
    
    foreach ($all_categories as $cat)
    {           
    
    if($cat->category_parent == 0)
     {
      $category_id = $cat->term_id;
       $thumbnail_id = get_woocommerce_term_meta( $cat->term_id,    'thumbnail_id', true );
    $image = wp_get_attachment_url( $thumbnail_id );
    
    echo '<li class="parent '.$my.' "><a href="'.get_term_link( $cat ) . '">'.$cat->name.'</a>';
    
    
    $args2 = array(
    'taxonomy' => $taxonomy,
    'child_of' => 0,
    'parent' => $category_id,
    'orderby' => $orderby,
    'show_count' => $show_count,
    'pad_counts' => $pad_counts,
    'hierarchical' => $hierarchical,
    'title_li' => $title,
    'hide_empty' => $empty
    
    );
       $args = array(
       'hierarchical' => 1,
       'show_option_none' => '',
       'hide_empty' => 0,
       'parent' => $parent_cat_ID,
       'taxonomy' => 'product_cat'
    );
     $subcats = get_categories($args2);
     echo '<ul class="wooc_sclist">';
    
      foreach ($subcats as $sc) { 
    
            }
    
        $link = get_term_link( $sc->slug, $sc->taxonomy );
        echo '<li class="'.$my.'" ><a href="'. $link .'">'.$sc->name.'</a></li>';
      }
    echo '</ul>';
    echo "</li>";
    }
    else
    {
    
     }
     }
    
        echo "</ul>";
       echo "</div>";
       echo "</div>";
    
  7. this is my approach, this works for product categories.

    $cat_args = array( 'orderby' => 'name', 'order' => 'asc', 'hide_empty' => true,);
    $cats = get_terms( 'product_cat', $cat_args );
    foreach ($cats as $key => $cat):
      if ($cat->parent == 0):
        echo $cat->name;
        foreach ($cats as $key => $cat2):
          if ($cat2->parent == $cat->term_id):
            echo $cat2->name;
            foreach ($cats as $key => $cat3):
              if ($cat3->parent == $cat2->term_id):
                echo $cat3->name;
              endif;
            endforeach;
          endif;
        endforeach;
      endif;
    endforeach;
    

Comments are closed.