I have a business directory and I have just added reviews. These are working as planned.
In the frontmatter of the listings, the review ratings are written as follows
“1/5”
“2/5”
“3/5”
“4/5”
“5/5”
I would like to display an average rating of the reviews for each listing.
Here is an example of the review frontmatter for a business listing with two reviews.
reviews:
review_1:
name: "Jason W"
date: "13th October 2022"
rating: "2/5"
activity: "Wildlife Experiences"
statement: "I am not happy with the experience. I was bored and couldn't wait to leave... Not impressed!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Apologies, please contact us for a full refund."
review_2:
name: "William K"
date: "14th October 2022"
rating: "4/5"
activity: "Wildlife Experiences"
statement: "Pretty good!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Thank you!"
How do I add the ratings and divide them by the number of reviews?
First, structure your front matter “reviews” as an array of reviews.
reviews:
- id: review_1
name: "Jason W"
date: "13th October 2022"
rating: 2
activity: "Wildlife Experiences"
statement: "I am not happy with the experience. I was bored and couldn't wait to leave... Not impressed!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Apologies, please contact us for a full refund."
- id: review_2
name: "William K"
date: "14th October 2022"
rating: 4
activity: "Wildlife Experiences"
statement: "Pretty good!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Thank you!"
To calculate average rating in your template:
{{ $ratingTotal := 0 }}
{{ range .Params.reviews }}
{{ $ratingTotal = add $ratingTotal .rating }}
{{ end }}
{{ $ratingAverage := div $ratingTotal (len .Params.Reviews) }}
Note that we are dividing one integer by another, which results in an integer. If you would prefer your average to be a float:
{{ $ratingAverage := div (float $ratingTotal) (len .Params.Reviews) }}
To display with one digit after the decimal point:
Although not required, I find this data structure is easier to comprehend, and it eliminates the need for a unique key for each review. So unless you need the key for some reason, you can simplify the front matter with:
reviews:
- name: "Jason W"
date: "13th October 2022"
rating: 2
activity: "Wildlife Experiences"
statement: "I am not happy with the experience. I was bored and couldn't wait to leave... Not impressed!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Apologies, please contact us for a full refund."
- name: "William K"
date: "14th October 2022"
rating: 4
activity: "Wildlife Experiences"
statement: "Pretty good!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Thank you!"
Thank you for your help. I have restructured the frontmatter and that all seems to be working without a hitch with my current reviews.
However, I am getting an error on the following:
{{ $ratingTotal := 0 }}
{{ range .Params.reviews }}
{{ $ratingTotal = add $ratingTotal .rating }}
{{ end }}
{{ $ratingAverage := div (float $ratingTotal) (len .Params.Reviews) }}
The error:
render of "page" failed: ".../themes/outlearn/layouts/directory-city/single.html:240:47": execute of template failed at <len .Params.Reviews>: error calling len: reflect: call of reflect.Value.Type on zero Value render of "page" failed: call of reflect.Value.Type on zero Value failed to render pages: call of reflect.Value.Type on zero Value
My frontmatter is currently:
reviews:
- name: "Jason W"
date: "13th October 2022"
rating: 2
activity: "Wildlife Experiences"
statement: "I am not happy with the experience. I was bored and couldn't wait to leave... Not impressed!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Apologies, please contact us for a full refund."
- name: "William K"
date: "14th October 2022"
rating: 3
activity: "Wildlife Experiences"
statement: "Pretty good!"
response:
name: "Geoff T"
date: "14th October 2022"
statement: "Thank you!"