WooCommerce – Turning the product tag cloud into a complex refine feature

Tags: , , , ,



QUESTION: How am I able to combine these two blocks of code so they work as one?

I do not require any shortcode solutions, I prefer the function format used in the first block of code, however the second block has some essential functionality.

The first block of code I have managed to construct allows for the WooCommerce product tag cloud to benefit from the following advanced features:

  • Alphabetised list.
  • Display product quantity totals.
  • Dynamic sizing and scrollable overflow box used if list becomes too long.
  • If a product archive level becomes empty (i.e. no ‘in stock’ products to show) then the whole tag level becomes hidden.
  • Hidden product tag levels then automatically 302 redirect themselves to the top level ‘shop’ page.

The code to achieve this is as follows:

/* TURN PRODUCT TAG CLOUD INTO ALPHABETICAL LIST WITH TAG TOTALS COUNT VISIBLE */

function woocommerce_product_tag_cloud_widget_filter($args) {
    $args = array(
        'smallest' => 14, 
        'largest' => 14, 
        'format' => 'list', 
        'taxonomy' => 'product_tag', 
        'unit' => 'px',
        'show_count' => 1,
        'number' => 0,
    );

    echo "<div style='padding-left: 20px; min-height: 50px; max-height: 400px; overflow: auto;'>";
    return $args;
    echo "</div>";
}

add_filter('woocommerce_product_tag_cloud_widget_args', 'woocommerce_product_tag_cloud_widget_filter');

/* HIDE PRODUCT TAG ARCHIVE PAGES WHEN THEY HAVE NO 'IN STOCK' PRODUCTS */

function hide_empty_tags( $terms, $taxonomies) {
    $new_terms = array();
    
    if ( in_array( 'product_tag', $taxonomies ) && ! is_admin() ) {
        foreach ( $terms as $key => $term ) {
            if ($term->count >0){
                $new_terms[] = $term;
            }
        }
        $terms = $new_terms;
    }
    return $terms;
}

add_filter( 'get_terms', 'hide_empty_tags', 10, 3 );

/* REDIRECTS TO SHOP IF THERE ARE NO 'IN STOCK' PRODUCTS IN THE PRODUCT TAG ARCHIVE PAGE */

function redirect_to_shop(){
    global $wp_query;

    if( is_woocommerce() && $wp_query->post_count == 0 ){
        the_post();
    $post_url = "/shop";
    wp_safe_redirect($post_url , 302 );
    exit;
    }
} 

add_action('template_redirect', 'redirect_to_shop');

The second block of code allows the product tag cloud to work dynamically in the same way you would expect a refine block to work – only showing relevant product tags at each product category level.

The shortcode is as follows:

[custom_product_tags]

The code is as follows:

add_shortcode('custom_product_tags', 'custom_product_tag_cloud_func');
function custom_product_tag_cloud_func() {
    if (is_shop()) {
        //return all tags
        $content = '<div class="widget_product_tag_cloud"><div class="tagcloud">';
        $tags = wp_tag_cloud(array(
            'format'                    => 'array',
            'taxonomy'                  => 'product_tag',
            'link'                      => 'view'
        ));
        foreach ($tags as $tag) {
            $content .= $tag;
        }
        $content .= '</div></div>';
        return $content;
    }
    global $wp;
    $current_slug = add_query_arg( array(), $wp->request );
    if(strpos($current_slug, '/') !== false) {
        // explodable
        $newtest = explode('/', $current_slug);
        $current_slug = array_pop($newtest);
    } 
    $args = array(
        'category' => array( $current_slug ),
        'limit' => -1
    );
    $products = wc_get_products( $args );
    $tags_objects = array();
    foreach ($products as $product) {
        $tags = get_the_terms( $product->get_id(), 'product_tag' );
        foreach ($tags as $tag) {
            $slug = $tag->slug;
            $cat_slug = add_query_arg( array(), $wp->request );
            $tag->link = get_site_url()."/".$cat_slug."?product_tag=".$slug;
            array_push($tags_objects, $tag);
        }
    }
    $tags_objects = array_unique($tags_objects, SORT_REGULAR);
    $tag_cloud = wp_generate_tag_cloud($tags_objects);
    $content = '<div class="widget_product_tag_cloud"><div class="tagcloud">';
    $content .= $tag_cloud;
    $content .= '</div></div>';
    return $content;
}

Answer

Try the below code Snippet:

/* CREATE A DYNAMIC PRODUCT TAG LIST - WITH SHORTCODE - WHICH ACTS DYNAMICALLY BASED ON WHERE YOU ARE WITHIN THE WEBSITE */

add_shortcode('dynamic_tag_cloud', 'custom_product_tag_cloud_func');

function custom_product_tag_cloud_func() {
   if (is_shop()) {
       $args= array(
           'smallest' => 14,
           'largest' => 14,
           'format' => 'list',
           'taxonomy' => 'product_tag',
           'unit' => 'px',
           'show_count' => 1,
           'number' => 0,
       );

       echo'<div class="widget woocommerce widget_product_tag_cloud"><span class="gamma widget-title">Related tags</span><div class="tagcloud" style="min-height: 50px; max-height: 300px; overflow: auto;"><ul class="wp-tag-cloud">';
       wp_tag_cloud($args);
       echo '</ul></div></div>';
   }

    global $wp;

    $current_slug = add_query_arg( array(), $wp->request );

    if(strpos($current_slug, '/') !== false) {
        $newtest = explode('/', $current_slug);
        $current_slug = array_pop($newtest);
    } 

    $args = array(
        'category' => array( $current_slug ),
        'limit' => -1,
    );

    $products = wc_get_products( $args );

    $tags_objects = array();

    foreach ($products as $product) {
        $tags = get_the_terms( $product->get_id(), 'product_tag' );
        
        foreach ($tags as $tag) {
            $slug = $tag->slug;
            $cat_slug = add_query_arg( array(), $wp->request );
            $tag->link = get_term_link( $tag ); //get_site_url()."/".$cat_slug."?product_tag=".$slug;
            array_push($tags_objects,$tag);
        }
    }

    $tags_objects = array_unique($tags_objects, SORT_REGULAR);
    
    $args = array(
        'smallest' => 14,
        'largest' => 14,
        'format' => 'list',
        'unit' => 'px',
        'show_count' => 1,
        'number' => 0,
    );

    $tag_cloud = wp_generate_tag_cloud($tags_objects,$args);
    
    if(is_product_category()){
        echo'<div class="widget woocommerce widget_product_tag_cloud"><span class="gamma widget-title">Related tags</span><div class="tagcloud" style="min-height: 50px; max-height: 300px; overflow: auto;"><ul class="wp-tag-cloud">';
        echo $tag_cloud;
        echo '</ul></div></div>';
    }
}


Source: stackoverflow