Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
19.3k views
in Technique[技术] by (71.8m points)

php - Hide WooCommerce empty product categories from WordPress menu

Based on Sort WooCommerce product category sub menu items by name ASC in Wordpress menu answer code to my previous question, I am able to automatically display child subcategories as menu sub items for some product categories in my WordPress navigation menu.

My question is: Is it possible to hide empty subcategories (sub menu items)?

And maybe if possible hide categories that contains only one product that is Sold Out.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can use additionally get_terms() with the following parameters:

  • 'include' to include all child terms from get_term_children() function as a coma separated string of term ids.
  • 'orderby' with 'name' attribute to sort terms by name,
  • 'order' with 'ASC' attribute to sort terms ascending,
  • 'hide_empty'with true attribute to not include empty terms.

So sorting will be made directly without requiring a foreach loop and you will get also directly an array of WP_Term objects.

The revisited code:

add_filter( 'wp_get_nav_menu_items', 'custom_submenu_product_categories', 10, 3 );
function custom_submenu_product_categories( $items, $menu, $args ) {
    // don't add child categories in administration of menus
    if (is_admin()) {
        return $items;
    }

    $taxonomy = 'product_cat';

    foreach ($items as $index => $post) {

        if ( $taxonomy !== $post->object ) {
            continue;
        }

        $children_terms_ids = get_term_children( $post->object_id, $taxonomy );

        if( ! empty($children_terms_ids) ) {
            $sorted_terms       = get_terms(array(
                'taxonomy'   => $taxonomy,
                'include'    => implode(',', $children_terms_ids),
                'orderby'    => 'name',
                'order'      => 'ASC',
                'hide_empty' => true,
            ));

            // Loop through sorted child terms to set them as sorted sub menu items
            foreach ( $sorted_terms as $index2 => $child_term ) {
                $item = new stdClass();

                $item->title            = $child_term->name;
                $item->url              = get_term_link( $child_term, $taxonomy );
                $item->menu_order       = 500 * ($index + 1) + $index2;
                $item->post_type        = 'nav_menu_item';
                $item->post_status      = 'published';
                $item->post_parent      = $post->ID;
                $item->menu_item_parent = $post->ID;
                $item->type             = 'custom';
                $item->object           = 'custom';
                $item->description      = '';
                $item->object_id        = 0;
                $item->db_id            = 0;
                $item->ID               = 0;
                $item->position         = 0;
                $item->classes          = array();
                $item->target           = ''; // <= Missing - Mandatory to avoid an error
                $item->xfn              = ''; // <= Missing - Mandatory to avoid an error

                $items[] = $item;
            }
        }
    }
    return $items;
}

Code goes in functions.php file of the active child theme (or active theme). Tested and works.

Now is not really possible to hide subcategories that contains only one product that are Sold Out, sorry.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...