-1

For aesthetics purposes, i chose to keep the menu from my theme (twentyfifteen).

I have a large catalog of products and i use Woocommerce to keep them into categories and products.

Everytime I add a new product I also have to add the product manually into the wordpress menu. Now that the website is getting bigger, i'll have a lot of new products and i'll always have to keep that up to date.

The Woocommerce widget "Woocommerce product category" adds automatically new products when they are set as child of a category.

Pictures to make it more understandable :

enter image description here

This is the menu i have. If i add a product in "storage cabinets" i will still have to go on the back-end and add it manually for it to show as a child of "storage cabinets".

Is there a way to add automatically a product into his right category as when i create it i set the category "storage cabinets" ?

Hope I could keep it clear and thank you for your replies. Don't hesitate to ask for clarifications as English is not my first language.

1 Answer 1

0

EDIT: I tried the following and it works in the theme "Storefront for woocommerce"(Though it needs additional styling). For some reason though, it does not work well with the twentyfifteen theme.(The submenu does not show.)

add_filter( 'wp_nav_menu_items', 'wc_products_on_nav_menu'); //filter to add the html
add_action( 'save_post_product', 'rebuild_custom_wc_nav_menu'); //action to regenerate the menu array anytime a product is added or updated

function build_wc_extra_menu(){
//get the product categories
$args = array(
     'taxonomy'     => 'product_cat',
     'orderby'      => 'name',
     'show_count'   => false,
     'pad_counts'   => false,
     'hierarchical' => true,
     'title_li'     => '',
     'hide_empty'   => false
);
$product_categories = get_categories( $args );

if(!empty($product_categories)){
    //get the products in each category
    foreach ($product_categories as $category){
        $cat_menu = array();
        $product_arg = array (
                'post_type'  => 'product',
                'post_status' => 'publish',
                'posts_per_page' => -1,
                'order'=> 'ASC',
                'product_cat' => $category->slug,
            );
        $products = get_posts($product_arg);
        foreach ($products as $product){
            //store the products as an associtive array with the name as key and link as value(will cause conflicts if two products have the same title)
            $link = get_post_permalink($product->ID);
            $cat_menu[$product->post_title] = $link;
        }
        //store the array of products as the value of an array with the key as the name of the category
        $custom_menu[$category->name] = $cat_menu;
    }
}
//save the entire array in the wp_options table
update_option('wc_cat_menu', $custom_menu);
}

function rebuild_custom_wc_nav_menu(){
//simply rebuild the array 
build_wc_extra_menu();
}

function wc_products_on_nav_menu($menu) { 
//check if the option exists, if not, rebuild the array
if(empty(get_option('wc_cat_menu'))) build_wc_extra_menu();
//retrieve the array from the wp_options table
$custom_menu = get_option('wc_cat_menu');
foreach ($custom_menu as $cat => $product_array){
    //build the html to append to the menu
    $cat_menu = '<li class="page_item">'.$cat.'<ul class="sub-menu">';
    foreach ($product_array as $name => $link){
        $product_submenu = '<li class="page_item"><a href="'.$link.'">'.$name.'</a></li>';
        $cat_menu = $cat_menu.$product_submenu;
    }
    $cat_menu = $cat_menu.'</ul></li>';
    //append the html to the menu
    $menu = $menu.$cat_menu;
}
//return the filtered menu
return $menu;  
}

EDIT: This code below was the original code. Don't use this!!! I'm leaving it here so because of the comments.

Try this. I did not run the code, so just try it out and comment if it works :)

add_filter( 'wp_nav_menu_items', 'wc_products_on_nav_menu');
//the filter hook to edit the nav_menu list

function wc_products_on_nav_menu($menu) {  
//first get all the product categories  
   $product_categories = get_terms( array(
    'taxonomy' => 'product_cat',
    'hide_empty' => true,
) );
if(!empty($product_categories)){
    foreach ($product_categories as $category){
 //add a top level list for the category name.
        $cat_menu = '<li>'.$category->name.'<ul>';
        $product_arg = array (
                'post_type'  => 'product',
                'post_status' => 'publish',
                'posts_per_page' => -1,
                'order'=> 'ASC',
                'product_cat' => $category->slug,
            );
        $products = get_posts($product_arg);
        foreach ($products as $product){
//add the products in that category as sub menu items
            $link = get_post_permalink($product->ID);
            $menu_item = '<li><a href="'.$link.'" >'.$product->post_title.'</a></li>';
            $cat_menu = $cat_menu . $menu_item;
        }
        $cat_menu = $cat_menu.'</ul></li>';
        $menu = $menu.$cat_menu;
    }
}
  return $menu;  
}
11
  • 1
    It's customary to include a little bit more explanation what your code does and why it should work.
    – cjbj
    Commented Jul 5, 2016 at 16:05
  • 1
    downvoted because this code is very not scaleable. You basically query all products in order to generate the menu on every page view. With huge ammount of product like the OP describe it is very likely to just bring down the site. A proper solution should probably be adding products to the menu when they are inserted Commented Jul 5, 2016 at 17:33
  • Yes!!! You're correct. I'll write a better answer Commented Jul 5, 2016 at 18:11
  • Don't try yet. It should work but will seriously slow down page load if you have many products. Commented Jul 6, 2016 at 6:19
  • Thank you for your work @StephenAfam-Osemene. I tried the code and it did not work. I am pretty new to Wordpress so i added it in my child functions.php . Is this where it belong ?
    – Relisora
    Commented Jul 6, 2016 at 6:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.