How do you add the star ratings for products in woocommerce?
Asked Answered
K

4

9

I have a woocommerce store and I want to add star ratings to each of the products when you see their thumbnails. I already have the stars in the big product view but I want them to display below each thumbnail like in most ecommerce stores like timberland.com. I know i can use css to disable items from view but not add them. Any thoughts?

Kawai answered 9/1, 2013 at 1:52 Comment(0)
E
16

You can put this into your themes functions.php file:

add_action('woocommerce_after_shop_loop_item', 'my_print_stars' );


function my_print_stars(){
    global $wpdb;
    global $post;
    $count = $wpdb->get_var("
    SELECT COUNT(meta_value) FROM $wpdb->commentmeta
    LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
    WHERE meta_key = 'rating'
    AND comment_post_ID = $post->ID
    AND comment_approved = '1'
    AND meta_value > 0
");

$rating = $wpdb->get_var("
    SELECT SUM(meta_value) FROM $wpdb->commentmeta
    LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
    WHERE meta_key = 'rating'
    AND comment_post_ID = $post->ID
    AND comment_approved = '1'
");

if ( $count > 0 ) {

    $average = number_format($rating / $count, 2);

    echo '<div class="starwrapper" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">';

    echo '<span class="star-rating" title="'.sprintf(__('Rated %s out of 5', 'woocommerce'), $average).'"><span style="width:'.($average*16).'px"><span itemprop="ratingValue" class="rating">'.$average.'</span> </span></span>';

    echo '</div>';
    }

}

Note that you may need to change woocommerce_after_shop_loop_item to a different hook depending on your design and where exactly you want the stars to show up.

This page lists WooCommerce action hooks: http://wcdocs.woothemes.com/codex/extending/hooks/ . I don't see any hooks associated with the thumbnail specifically, but you may try woocommerce_after_shop_loop_item_title or woocommerce_after_shop_loop_item.

(This function is essentially copied from WooCommerce's single-product-reviews.php)

Extrusion answered 26/1, 2013 at 17:32 Comment(1)
This shouldn't be the accepted answer. Using sql directly in a plugin file is dangerous, and can lead to computability issues with future updates. Martyn's or ryanka's answer below should be the recommended answer.Th
I
19

There's actually a much more terse way to handle this. Just use the built-in functions that Woocommerce has built out:

add_action('woocommerce_after_shop_loop_item', 'get_star_rating' );
function get_star_rating()
{
    global $woocommerce, $product;
    $average = $product->get_average_rating();

    echo '<div class="star-rating"><span style="width:'.( ( $average / 5 ) * 100 ) . '%"><strong itemprop="ratingValue" class="rating">'.$average.'</strong> '.__( 'out of 5', 'woocommerce' ).'</span></div>';
}

I've confirmed that this works for me.

Intoxicated answered 27/12, 2013 at 3:44 Comment(1)
Don't forget to check that the woocommerce plugin is enabled by wrapping the above code in an if condition: if (in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { ... }Finochio
E
16

You can put this into your themes functions.php file:

add_action('woocommerce_after_shop_loop_item', 'my_print_stars' );


function my_print_stars(){
    global $wpdb;
    global $post;
    $count = $wpdb->get_var("
    SELECT COUNT(meta_value) FROM $wpdb->commentmeta
    LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
    WHERE meta_key = 'rating'
    AND comment_post_ID = $post->ID
    AND comment_approved = '1'
    AND meta_value > 0
");

$rating = $wpdb->get_var("
    SELECT SUM(meta_value) FROM $wpdb->commentmeta
    LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
    WHERE meta_key = 'rating'
    AND comment_post_ID = $post->ID
    AND comment_approved = '1'
");

if ( $count > 0 ) {

    $average = number_format($rating / $count, 2);

    echo '<div class="starwrapper" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">';

    echo '<span class="star-rating" title="'.sprintf(__('Rated %s out of 5', 'woocommerce'), $average).'"><span style="width:'.($average*16).'px"><span itemprop="ratingValue" class="rating">'.$average.'</span> </span></span>';

    echo '</div>';
    }

}

Note that you may need to change woocommerce_after_shop_loop_item to a different hook depending on your design and where exactly you want the stars to show up.

This page lists WooCommerce action hooks: http://wcdocs.woothemes.com/codex/extending/hooks/ . I don't see any hooks associated with the thumbnail specifically, but you may try woocommerce_after_shop_loop_item_title or woocommerce_after_shop_loop_item.

(This function is essentially copied from WooCommerce's single-product-reviews.php)

Extrusion answered 26/1, 2013 at 17:32 Comment(1)
This shouldn't be the accepted answer. Using sql directly in a plugin file is dangerous, and can lead to computability issues with future updates. Martyn's or ryanka's answer below should be the recommended answer.Th
C
4

As of WooCommerce 3.0+ this is the correct code:

$product = wc_get_product( $id );
echo wc_get_rating_html( $product->get_average_rating() );

The get_rating_html() method on the product object has been deprecated.

More information here: https://docs.woocommerce.com/wc-apidocs/function-wc_get_rating_html.html

Celebrity answered 14/9, 2017 at 15:17 Comment(0)
S
1

With those functions (or the shorter one below, which outputs the same HTML), you manage to output the rating in numbers, reusing Woocommerce's functions completely:

function get_star_rating() {
    global $woocommerce, $product;
    /*$average = $product->get_average_rating();*/
    echo $product->get_rating_html();
}

Then you need to style it to show the stars. For a rating of 3 out of 5 stars, Woothemes does it like this (the trick is in the width and :before of the corresponding CSS):

HTML (output by Woocommerce):

<div itemprop="reviewRating" itemscope="" itemtype="http://schema.org/Rating" class="star-rating" title="Rated 3 out of 5">
    <span style="width:60%"><strong itemprop="ratingValue">3</strong> out of 5</span>
</div>

And the CSS (there may be some redundant lines in here):

#reviews .comment .star-rating {
    float: none;
    font-size: 1em;
    margin: 0;
    position: absolute;
    top: 2px;
    right: 20px;
}
.star-rating {
    overflow: hidden;
    height: 1em;
    line-height: 1em;
    width: 5.1em;
    font-family: "fontawesome";
}

.star-rating:before {
    content: "\f006\f006\f006\f006\f006";
    float: left;
    top: 0;
    left: 0;
    position: absolute;
    letter-spacing: 0.1em;
    letter-spacing: 0\9;
    color: #fbfeff;
}

.star-rating span {
    overflow: hidden;
    float: left;
    top: 0;
    left: 0;
    position: absolute;
    padding-top: 1.5em;
}

.star-rating span:before {
    content: "\f005\f005\f005\f005\f005";
    top: 0;
    position: absolute;
    left: 0;
    letter-spacing: 0.1em;
    letter-spacing: 0\9;
    color: #f36557;
}

.star-rating {
    line-height: 1em;
    font-size: 1em;
    font-family: "fontawesome";
}

Hope that helps!

Stanislas answered 20/1, 2014 at 15:18 Comment(3)
Ok, right after posting this I finally found this is done via CSS. Woothemes are great examples of how it's donde, in case anyone's wondering. Thanks anyway!Stanislas
So maybe go ahead and post how you did it for the rest of us to see..??Mal
Well, I did say how I did it. You just had to go and inspect any woocommerce theme by woothemes. I didn't put up the code because I don't know if that's really fair... but anyway, I've edited the answer with the code. I would go the original source still. Hope this clarifies it a bit though. Cheers!Stanislas

© 2022 - 2024 — McMap. All rights reserved.