Search code examples
phpwordpresswoocommercethumbnailscustom-taxonomy

Get and display the product category featured image in Woocommerce


I'm making my first theme and everything is progressing real fast thanks to all the assistance offered by The Loop and WooCommerce's SDK. Then today I spent an entire day failing to do something as simple as showing an image... After an entire day of struggling the only things I managed to learn is that WP seems to offer NO means for fetching a category's image and MANY people have asked this question for many years and STILL I can't find a way to ACTUALLY do it... :(

What I want to do is create a slider above my store that shows the images of a curated selection of shop categories. I want to be able to enter a list of term names and based on that my function should generate links to the product categories in the form of the category's image.

Sounds simple... turns out, it's nowhere near CLOSE to simple... Before you go off and mark this as a duplicate question, let me explain why I am asking it...

Some of the solutions I have found require that I know the term's IDs, not the tern name. Some say "Get the id's using a custom term search" but doesn't explain how. I know how to do custom taxonumy based queries for posts but not for terms. the documentation confuses me in terms of what values to pass to query terms :(

Other solutions require that I first find a product of a specific category and then find the product's category image working backwards from there (????)

Then of course there is the default answer people love to give for everything: "Oh you are designing your own theme and want to show category icons? Simple, just download a plugin to do that for you". Now why didn't I think of just including someone else's plugin into my theme? (facepalm)

Other answers just show how to print the list of term names but nothing so far has been able to let me do what should have been been as simple as this:

$categories = array("software", "plugins", "merch");
foreach($categories as $cat) {
    $term_id = get_term_id($cat);
    $term_image = get_term_featured_image($term_id);
    echo '<img src="'.$term_image.'">;
    }

First problem with getting the term is that the wordpress function to get the term id only works on the category taxonomy but I need to query WooCommerce's product_cat taxonomy. Secondly there doesn't seem to be an option to fetch the thumbnail/featured image even if you HAVE an id. So now what?

So I went low level and started querying the tables directly using $wpdb and I determine the term I am after has term_id 94. I query the termmeta table for the thumbnail's post ID and I find it is 905. Now I turn to my posts table and find.... there IS no post entry 905! WTF? So I do this for two more categories and find the same thing. Finding the image's id results in nothing being returned from the attempt at extracting the post's attachments since there IS no post matching the image's id...

Why is this so darned hard? WordPress makes everything else so incredibly simple yet this simple sounding task seems to be near impossible to do... so now that you see I have Googled this to death and struggled my backside off already, I am asking this question out of desperation:

How do I take an array of product_cat term names and convert that into an array of url's to display the category's image?

Thanks


Solution

  • The shortest way is to use woocommerce_subcategory_thumbnail() dedicated function:

    $product_categories = array("software", "plugins", "merch");
    
    // Loop through the product categories
    foreach( $product_categories as $category ) {
        // Get the WP_term object
        $term = get_term_by( 'slug', sanitize_title( $category ), 'product_cat' );
    
        // Get the term link (if needed)
        $term_link = get_term_link( $term, 'product_cat' );
    
        // Display the product category thumbnail
        woocommerce_subcategory_thumbnail( $term );
    }
    

    The other step by step way, that will display the linked product category image with its name:

    $product_categories = array("software", "plugins", "merch");
    
    // Loop through the product categories
    foreach( $product_categories as $category ) {
        // Get the WP_term object
        $term = get_term_by( 'slug', sanitize_title( $category ), 'product_cat' );
    
        // Get the term link (if needed)
        $term_link = get_term_link( $term, 'product_cat' );
    
        // Get the thumbnail Id
        $thumbnail_id  = (int) get_woocommerce_term_meta( $term->term_id, 'thumbnail_id', true );
    
        if( $thumbnail_id > 0 ) {
            // Get the attchement image Url
            $term_img  = wp_get_attachment_url( $thumbnail_id );
    
            // Formatted thumbnail html
            $img_html = '<img src="' . $term_img . '">';
        } else {
            $img_html = '';
        }
        echo '<a href="' . $term_link . '">' . $img_html . $term->name . '</a><br>';
    }
    

    Both works…


    To get all product categories WP_Term objects and display them with their thumbnails:

    // Get all product categories
    $product_category_terms = get_terms( array(
        'taxonomy'   => "product_cat",
        'hide_empty' => 1,
    ));
    
    foreach($product_category_terms as $term){
        // Get the term link (if needed)
        $term_link = get_term_link( $term, 'product_cat' );
    
        ## -- Output Example -- ##
    
        // The link (start)
        echo '<a href="' . $term_link . '" style="display:inline-block; text-align:center; margin-bottom: 14px;">';
    
        // Display the product category thumbnail
        woocommerce_subcategory_thumbnail( $term );
    
        // Display the term name
        echo $term->name;
    
        // Link close
        echo '</a>';
    }