Home › Toolset Professional Support › [Resolved] How to get rating average from CRED for review
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | 9:00 – 13:00 | - |
- | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | - |
Supporter timezone: Asia/Hong_Kong (GMT+08:00)
This topic contains 43 replies, has 11 voices.
Last updated by joeC-5 9 years, 11 months ago.
Assigned support staff: Luo Yang.
Hey guys, I am referring in part to this topic here: https://toolset.com/forums/topic/creating-a-review-site-star-ratings-and-schema-org/, however, I will describe the issue again for convenience sake. I would also like to add this to your feature requests as this is an important function for any review site and you actually use a review site as an example - hence, I think it would be an important addition to views in the near future.
I have Custom Post Types (CPT) built in Types. One is called Restaurants and one is called Reviews. Reviews is a child of Restaurants.
I have Custom Fields, and amongst other things I have a field called ratings. These ratings are a radio button field which gives values for people to vote rate 1,2,3,4,5 for a restaurant . With CSS, these values display stars on the site.
I then built a CRED form for people to submit their review. They have, among others, the Ratings to choose from. So they would select something between 1 and 5 in the radio buttons to rate the restaurant they are reviewing.
So far so good. All that works just fine - the stars are displayed on the review next to the author who rated it - but there is one very important element a review site needs. That is to display the AVERAGE rating a post received and the number of votes actually on the item being reviewd - in my case a restaurant.
So if 4 people gave a post 4 stars, 1 gave the post 3 stars and 5 gave the post 5 stars, then I need something to calculate the average and display the result average 4.4.
How do I go about this please? I found this code I could possibly modify for use with toolset, but I am currently a bit lost.
<?php $count = count($array); $sum = array_sum($array); $average = $added / $count; echo $average; ?>
Could someone assist me to get my head around this what I thought would be an easy thing to do but which has now cost me loads of cups of coffee? I really, really, but really do not want to use a separate plugin for this - really!
Thanks
Languages: English (English ) Chinese (Simplified) (简体中文 )
Timezone: Asia/Hong_Kong (GMT+08:00)
Hi triggeru571,
I assume your CPT Reviews is suing slug "reviews", Custom Fields ratings is using slug ratings, please try create a WP shortcode for it, like this:
1) add codes in your theme/functions.php:
add_shortcode('rating-average', 'rating_average_func'); function rating_average_func() { $child_posts = types_child_posts('reviews'); $sum = 0; $num = 0; foreach ($child_posts as $child_post) { if(isset($child_post->fields['ratings'])) { $sum += $child_post->fields['ratings']; $num ++; } } $res = ''; if($num>0) { $res = $sum/$num; } return $res; }
2) put the shortcode [rating-average] into your Restaurants post content, for example:
This Restaurants AVERAGE rating is: [rating-average]
More help:
Displaying child posts using Types PHP functions
Alternatively, you can load child posts using Types types_child_posts API function.
https://toolset.com/documentation/user-guides/querying-and-displaying-child-posts/
Close but not quite. The shortcode is returning 0 as average. Here is my code live
// Adds Calculation of average and shortcode for ratings add_shortcode('rating-average', 'rating_average_func'); function rating_average_func() { $child_posts = types_child_posts('restaurant-cafe-rev'); $sum = 0; $num = 0; foreach ($child_posts as $child_post) { if(isset($child_post->fields['ratings'])) { $sum += $child_post->fields['ratings']; $num ++; } } $res = ''; if($num>0) { $res = $sum/$num; } return $res; }
Languages: English (English ) Chinese (Simplified) (简体中文 )
Timezone: Asia/Hong_Kong (GMT+08:00)
I can not duplicate in my localhost, the above codes works for me, could you send the login details of your website to my email?
This has worked now. It was just a booboo from my end which caused it not to work 🙂 So now lets push it one final step further and we have a fully fledged review site with star ratings for Toolset which includes Schema - how great is that 🙂
So with the above code, I have a result of 2.5 average - It's perfect. But now, I want to display stars which have 2.5 as their value. I also want to have that value rounded up or down to the nears Half decimal. So for instance, an average of 2.6 or 2.7 would display the 2.5 stars, and those with a 2.8 and 2.9 average would display a 3 star rating.
In my View code I have the following setup for each review:
<!-- wpv-loop-start --> <wpv-loop> <div><strong>[wpv-post-title]</strong> | <img src="<em><u>hidden link</u></em> field="ratings"][/types].png" alt="Rated [types field="ratings"][/types] out of 5"/></div> <div><strong>Review by:</strong> [wpv-post-author] on [wpv-post-date]</div> <div>[wpv-post-body view_template="None"] <hr /> </div> </wpv-loop>
Where:
<img src="<em><u>hidden link</u></em> field="ratings"][/types].png/>
takes the value of the short code of the custom fields [ratings] and adds it to the stars to become something like this stars1.png (which displays 1 star).
For the average, I now need to display the average star rating so the code will look like
<img src="<em><u>hidden link</u></em>;
Of course, I cannot create stars for every combination of averages, but I can create a 1.5, 2.5, 3.5 etc. I would have to name these new stars as star15.png, star2.5.png etc for this to be able to work.
How do I go about rounding up/down the average value result and remove the decimal point to then use this to display the average star rating
BTW, we also need to count the number of reviews to display these next to the ratings as it is a requirement for Schema. How do we do that? So basically now we need
[rating_average] based on [reviews_total] as our two short codes.
one last thing, I just realised that if there is no ratings present, then the shortcode does not display any rating at all - it returns a blank value. It needs to actually return 0
Languages: English (English ) Chinese (Simplified) (简体中文 )
Timezone: Asia/Hong_Kong (GMT+08:00)
1) How do I go about rounding up/down the average value result and remove the decimal point to then use this to display the average star rating
Please try this:
add_shortcode('rating-average', 'rating_average_func'); function rating_average_func() { $child_posts = types_child_posts('reviews'); $sum = 0; $num = 0; foreach ($child_posts as $child_post) { if(isset($child_post->fields['ratings'])) { $sum += $child_post->fields['ratings']; $num ++; } } $average = 0; if($num>0) { $average = $sum/$num; } $res = $average; if($average==0) $res = 0; if($average<0.8) $res = 0.5; if($average>0.8 && $average<1) $res = 1; //... here put more condition ... return $res; }
2) [reviews_total] shortcode:
add_shortcode('reviews_total', 'reviews_total_func');
function reviews_total_func()
{
$child_posts = types_child_posts('reviews');
return count($child_posts);
}
[/php]
3) it is fixed in 1)
Great stuff. All works like a charm now! Stars appear correctly, number of reviews too and all coded with Schema so the search engines can grab the snippet and show the review stars in their search results. I will share how to do this with the community once I get my head around a few other unrelated issues. Thanks a million Luoy.
I just want to say that this is by far the most helpful and useful thread I've read to date. I'm looking to do the exact same thing and felt the book review site stopped a little short of what most users want.
Thank You Luoy and triggeru571!
Welcome, BryanG, let me know if you need any help for this especially with regard to the Schema as mine validates on the Google Structured Data Testing tool with the Star rating showing up in the search result snippet. 🙂
Fantastically useful post. thank you triggeru571 and luoy.
I've been looking to do something similar and had visions of having to do all sorts of things with extra plugins and and and...
Will have to restudy this thread and do some experimenting
Thanks 🙂
triggeru571 if you're about.. are you able to possibly point me to any information on how I can create the star ratings?
I can do it via the use of another plugin but would prefer not to if there is another way to do it.
Any help would be appreciated
Thanks
Bronwyn
Hi Bronwyn, sure I can. Here is a quick overview of what is above. I will create something a bit more detaild to post to the community in a couple of weeks but for now this should suffice. Follow the steps and you should be OK
1) Create a new Custom Field, name it 'rating' and choose Radio Buttons. You need to give each button the following values 0,1,2,3,4,5 and select 0 as default. Create any other fields you may need for your reviews. In my case I had review title and description.
2) Create a Custom Post Type and name it 'reviews'
3) Create a CRED form to display the fields you just created in your Custom Field.
4) Add the code below to your functions.php file. I placed mine in a custom functions file to keep my file clean, but if you do not have one, funtions.php will be fine
//Calculates and displays the Average Rating of a post add_shortcode('rating-average', 'rating_average_func'); function rating_average_func() { $child_posts = types_child_posts('reviews'); $sum = 0; $num = 0; foreach ($child_posts as $child_post) { if(isset($child_post->fields['ratings'])) { $sum += $child_post->fields['ratings']; $num ++; } } $average = 0; if($num>0) { $average = $sum/$num; } $res = $average; if($average==0) $res = 0; if($average>0.001 && $average<0.5)$res = 0.5; if($average>0.501 && $average<1) $res = 1; if($average>1.001 && $average<1.5) $res = 1.5; if($average>1.501 && $average<2) $res = 2; if($average>2.001 && $average<2.5) $res = 2.5; if($average>2.501 && $average<3) $res = 3; if($average>3.001 && $average<3.5) $res = 3.5; if($average>3.501 && $average==4) $res = 4; if($average>4.001 && $average<4.5) $res = 4.5; if($average>4.501 && $average<5) $res = 5; //... here put more condition ... return $res; }
What we have done above is create the short code to display the average rating in increments of 0.5. Your short code will now be
[rating_average]
5) Add this code beneath the code above
//Calculates and displays the number of reviews in a post [reviews_total] shortcode: add_shortcode('reviews_total', 'reviews_total_func'); function reviews_total_func() { $child_posts = types_child_posts('reviews'); return count($child_posts); }
With the code above, we are counting the number of reviews we have in a post. This is an important function for Schema. The short code created by this is:
[reviews_total]
6) Next in line, you need to create your stars (or any imagery you want). In total you are going to have to create 11 images for the following options: 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5 . Give each image a name + the value assigned to it. For example, mine are called stars0.png, stars0.5.png, stars1.png etc. Upload them to your folder. Mine is uploaded to a folder 'ratings which I created in my main images folder: images/ratings.
7) Go to the View which will generate the necessary loop to display your reviews and add the following code:
<!-- wpv-loop-start --> <wpv-loop> <div><strong>[wpv-post-title]</strong> | <img src="<em><u>hidden link</u></em> field="ratings"][/types].png" alt="Rated [types field="ratings"][/types] out of 5"/></div> <div><strong>Review by:</strong> [wpv-post-author] on [wpv-post-date]</div> <div>[wpv-post-body view_template="None"] <hr /> </div> </wpv-loop>
Note what has been done here. We have called [types field="ratings"][/types] and placed it to replace the value of the star within our image, so that star1.png becomes
star[types field="ratings"][/types].png
So now when your view is loaded on the front end, the types shortcode will be replaced by the value selected on the review and will display your star images.
8) Go to your Content Template which your reviewd item will be using, and put this code in it. Place it where you want your star rating to appear.
<div class="rating-box"> <span itemprop="aggregateRating" itemscope itemtype="<em><u>hidden link</u></em>"> <meta itemprop="ratingValue" content="[Rated [rating-average] out of 5]"> <img src="<em><u>hidden link</u></em>" alt="Rated [rating-average] out of 5"/> from <span itemprop="ratingCount">[reviews_total]</span> reviews. </span></div>
On my view template, I also called the View which displays the actual reviews and the individual star ratings given by each reviewer (step 7).
9) Make sure all the paths and file names are correct for your own site settings. Give one of your items a review with stars and check it out on the front end. It should now display your stars.
A word on Schema:
You need to customize the Schema depending on what your site is. You already have a sample of how it would look like in (8) above and you can leave the values as they are. However, for the snippets to show up in the search engine, you need to add much more into your Content Template (ex: type of Schema you will use, product name etc.) . Many of the tutorials out there are good though for some reason many say Schema is complex. IT IS NOT and its as easy as writing basic HTML.
Hope I did not forget anything above and that it works fine for you. Do not forget to check the values in all the codes to make sure they correspond with your own on your site. 🙂
Just realized I have two errors above:
In point number 1 "Create a new Custom Field, name it 'rating' and choose Radio Buttons." Name your custom field ratings not rating.
In point number 4 where the code is
if($average>3.501 && $average==4) $res = 4;
should be
if($average>3.501 && $average<4) $res = 4;