I'm working on a website that uses Schema.org microdata for structured content product listings and apparently Google requires an aggregate rating of all the reviews. How can I grab all of the
<meta itemprop="ratingValue" content="#" />
tags and then average them into a variable I can output to:
<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
<meta itemprop="ratingValue" content="average #" />
<meta itemprop="reviewCount" content="# reviews" />
</div>
using JQuery or JavaScript? (Where # = the rating value)
Yes, this is not too difficult using jQuery. This code will grab all the meta contents, convert them to integers, find the average rating, and then append some HTML
at the bottom of your head
element.
// first gather all the meta elements with an itemprop value of "ratingValue"
var metas = $('meta[itemprop="ratingValue"]').get();
// convert the content values of these elements to integers and put them in an array
var ratings = metas.map((m) => ~~m.content);
// calculate and round the average rating value
var average = ~~(ratings.reduce((a,b) => a + b) / ratings.length + 0.5);
// create the HTML for the aggregateRating parent div
var aggregateRating = '<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">';
// create ratingValue meta HTML using the average rating
var ratingValue = '<meta itemprop="ratingValue" content="average ' + average + '" />';
// create aggregateRating meta HTML using the rating count
var reviewCount = '<meta itemprop="reviewCount" content="' + ratings.length + ' reviews" />';
// combine these strings and a closing tag, then append the HTML to the end of head
$('head').append(aggregateRating + ratingValue + reviewCount + '</div>');
or you could even use the Bernard method
$('head').append(['<div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">', '</div>'].join([
['ratingValue', 'average ' + ~~((r = $('meta[itemprop="ratingValue"]').get().map((m) => ~~m.content)).reduce((a, b) => a + b) / r.length + .5)],
['reviewCount', r.length + ' reviews']
].map((a, b) => ['<meta itemprop="', '" content="', '">'].map((c, d) => [c, a[d]]))).replace(/,/g, ''));