coreFORCE - Website: How to add Google Reviews
How to add Google Reviews
- Generate a Google API Key
To get Google Reviews using the Google Places API, you’ll need to follow these steps to set up and use the Google Places API. Here’s a comprehensive guide: https://developers.google.com/maps/documentation/embed/get-api-key
Add this script with Google API Key in the header part of the template
undefined<script src="//maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&key=YOUR_API_KEY"></script>
- Include these on the page where you want it to be displayed
Data Tab
<section class="reviews-container">
<div class="grid-container">
<div class="product-header">
<h2>Testimonials</h2>
</div>
<div id="google-reviews" class="testimonial-wrapper reviews-content"></div>
<h3 class="text-center loading-reviews">
No reviews available yet.
</h3>
</div>
</section>
CSS Tab
.reviews-container {
padding: 1rem 0 1rem;
margin-bottom: 2rem;
.product-header {
h2 {
margin-bottom: 1rem;
color: $secondary-color;
font-size: 1.5rem;
}
}
.testimonial-wrapper {
.review-item {
margin: 0 10px;
text-align: center;
border-radius: 0.5rem;
border: 1px solid #707070;
padding: 2rem 1rem;
background: #f1eded;
.star-container {
margin: 0;
li {
display: inline-block;
vertical-align: middle;
margin: 0.2em;
i {
color: $secondary-color;
font-size: 1.5em;
}
}
}
.review-text {
margin: 0;
font-size: 1.1rem;
font-weight: normal;
}
.review-author {
color: black;
font-size: 1.1rem;
font-weight: bold;
margin-bottom: 1rem;
}
.review-stars {
margin-top: 2rem;
}
}
}
}
Javascript tab (Template)
You must edit the locationPlaceID when adding this script; if you are unsure about it, you can find it here.
$(function () {
testimonial();
)
function testimonial() {
const locationPlaceId = "YOUR_LOCATION_PLACE_ID";
var namespace = "googlePlaces";
$.googlePlaces = function (element, options) {
var defaults = {
placeId: locationPlaceId, // placeId provided by google api documentation
render: ["reviews"],
min_rating: 10,
max_rows: 0,
map_plug_id: "map-plug",
rotateTime: false,
shorten_names: false,
schema: {
displayElement: "#schema",
type: "Store",
beforeText: "Google Users Have Rated",
middleText: "based on",
afterText: "ratings and reviews",
image: null,
priceRange: null
},
address: {
displayElement: "#google-address"
},
phone: {
displayElement: "#google-phone"
},
staticMap: {
displayElement: "#google-static-map",
width: 512,
height: 512,
zoom: 17,
type: "roadmap"
},
hours: {
displayElement: "#google-hours"
}
};
var plugin = this;
plugin.settings = {};
var $element = $(element),
element = element;
plugin.init = function () {
plugin.settings = $.extend({}, defaults, options);
plugin.settings.schema = $.extend({}, defaults.schema, options.schema);
$element.html("<div id='" + plugin.settings.map_plug_id + "'></div>"); // create a plug for google to load data into
initialize_place(function (place) {
plugin.place_data = place;
// Trigger event before render
$element.trigger("beforeRender." + namespace);
if (plugin.settings.render.indexOf("rating") > -1) {
renderRating(plugin.place_data.rating);
}
// render specified sections
if (plugin.settings.render.indexOf("reviews") > -1) {
renderReviews(plugin.place_data.reviews);
if (!!plugin.settings.rotateTime) {
initRotation();
}
}
if (plugin.settings.render.indexOf("address") > -1) {
renderAddress(
capture_element(plugin.settings.address.displayElement),
plugin.place_data.adr_address
);
}
if (plugin.settings.render.indexOf("phone") > -1) {
renderPhone(
capture_element(plugin.settings.phone.displayElement),
plugin.place_data.formatted_phone_number
);
}
if (plugin.settings.render.indexOf("staticMap") > -1) {
renderStaticMap(
capture_element(plugin.settings.staticMap.displayElement),
plugin.place_data.formatted_address
);
}
if (plugin.settings.render.indexOf("hours") > -1) {
renderHours(
capture_element(plugin.settings.hours.displayElement),
plugin.place_data.opening_hours
);
}
// render schema markup
addSchemaMarkup(
capture_element(plugin.settings.schema.displayElement),
plugin.place_data
);
// Trigger event after render
$element.trigger("afterRender." + namespace);
});
};
var capture_element = function (element) {
if (element instanceof jQuery) {
return element;
} else if (typeof element == "string") {
try {
var ele = $(element);
if (ele.length) {
return ele;
} else {
throw (
"Element [" +
element +
"] couldnt be found in the DOM. Skipping " +
element +
" markup generation."
);
}
} catch (e) {
console.warn(e);
}
}
};
var initialize_place = function (c) {
var map = new google.maps.Map(
document.getElementById(plugin.settings.map_plug_id)
);
var request = {
placeId: plugin.settings.placeId
};
var service = new google.maps.places.PlacesService(map);
service.getDetails(request, function (place, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
c(place);
}
});
};
var sort_by_date = function (ray) {
ray.sort(function (a, b) {
var keyA = new Date(a.time),
keyB = new Date(b.time);
// Compare the 2 dates
if (keyA < keyB) return -1;
if (keyA > keyB) return 1;
return 0;
});
return ray;
};
var filter_minimum_rating = function (reviews) {
for (var i = reviews.length - 1; i >= 0; i--) {
if (reviews[i].rating < plugin.settings.min_rating) {
reviews.splice(i, 1);
}
}
return reviews;
};
// var renderRating = function (rating) {
// var html = "";
// var star = renderAverageStars(rating);
// html = "<div class='average-rating'><h4>" + star + "</h4></div>";
// $element.append(html);
// };
var shorten_name = function (name) {
if (name.split(" ").length > 1) {
var xname = "";
xname = name.split(" ");
return xname[0] + " " + xname[1][0] + ".";
}
};
var renderReviews = function (reviews) {
var filteredReviews = reviews.filter(function (review) {
return review.rating === 5;
});
var html = "";
var row_count =
plugin.settings.max_rows > 0
? plugin.settings.max_rows - 1
: filteredReviews.length - 1;
// make sure the row_count is not greater than available records
row_count =
row_count > filteredReviews.length - 1 ? filteredReviews.length - 1 : row_count;
for (var i = row_count; i >= 0; i--) {
var stars = renderStars(filteredReviews[i].rating);
var date = convertTime(filteredReviews[i].time);
if (plugin.settings.shorten_names == true) {
var name = filteredReviews[i].author_name;
} else {
var name =
filteredReviews[i].author_name +
"</span>";
}
html +=
"<div class='review-item'>" +
"<p class='review-text readmore js-read-more' data-rm-words='30'>" +
filteredReviews[i].text +
"</p>" + "<div class='review-meta'><span class='review-author'>- " + name + stars +
"</div></div>";
}
$element.append(html);
};
var renderStars = function (rating) {
var stars = "<div class='review-stars'><ul class='star-container'>";
// fill in gold stars
for (var i = 0; i < rating; i++) {
stars = stars + "<li><i class='fa star fa-star'></i></li>";
}
// fill in empty stars
if (rating < 5) {
for (var i = 0; i < 5 - rating; i++) {
stars = stars + "<li><i class='fa fa-star star inactive'></i></li>";
}
}
stars = stars + "</ul></div>";
return stars;
};
var renderAverageStars = function (rating) {
var stars =
"<div class='review-stars'><ul><li><i>" + rating + " </i></li>";
var activeStars = parseInt(rating);
var inactiveStars = 5 - activeStars;
var width = (rating - activeStars) * 100 + "%";
// fill in gold stars
for (var i = 0; i < activeStars; i++) {
stars += "<li><i class='fa fa-star star'></i></li>";
}
// fill in empty stars
if (inactiveStars > 0) {
for (var i = 0; i < inactiveStars; i++) {
if (i === 0) {
stars +=
"<li style='position: relative;'><i class='fa fa-star inactive star'></i><i class='fa fa-star star' style='position: absolute;top: 0;left: 0;overflow: hidden;width: " +
width +
"'></i></li>";
} else {
stars += "<li><i class='inactive star fa-fa-star'></i></li>";
}
}
}
stars += "</ul></div>";
return stars;
};
var convertTime = function (UNIX_timestamp) {
var a = new Date(UNIX_timestamp * 1000);
var months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
];
var time =
months[a.getMonth()] + " " + a.getDate() + ", " + a.getFullYear();
return time;
};
var addSchemaMarkup = function (element, placeData) {
if (element instanceof jQuery) {
var schema = plugin.settings.schema;
var schemaMarkup =
'<span itemscope="" itemtype="http://schema.org/' +
schema.type +
'">';
if (schema.image !== null) {
schemaMarkup += generateSchemaItemMarkup("image", schema.image);
} else {
console.warn(
"Image is required for some schema types. Visit https://search.google.com/structured-data/testing-tool to test your schema output."
);
}
if (schema.priceRange !== null) {
schemaMarkup += generateSchemaItemMarkup(
"priceRange",
schema.priceRange
);
}
schemaMarkup += generateSchemaItemMarkup("url", location.origin);
schemaMarkup += generateSchemaItemMarkup(
"telephone",
plugin.place_data.formatted_phone_number
);
schemaMarkup += generateSchemaAddressMarkup();
schemaMarkup += generateSchemaRatingMarkup(placeData, schema);
schemaMarkup += "</span>";
element.append(schemaMarkup);
}
};
var generateSchemaAddressMarkup = function () {
var $address = $("<div />", {
itemprop: "address",
itemscope: "",
itemtype: "http://schema.org/PostalAddress"
}).css("display", "none");
$address.append(plugin.place_data.adr_address);
$address.children(".street-address").attr("itemprop", "streetAddress");
$address.children(".locality").attr("itemprop", "addressLocality");
$address.children(".region").attr("itemprop", "addressRegion");
$address.children(".postal-code").attr("itemprop", "postalCode");
$address.children(".country-name").attr("itemprop", "addressCountry");
return $address[0].outerHTML;
};
var generateSchemaRatingMarkup = function (placeData, schema) {
var reviews = placeData.reviews;
var lastIndex = reviews.length - 1;
var reviewPointTotal = 0;
for (var i = lastIndex; i >= 0; i--) {
reviewPointTotal += reviews[i].rating;
}
var averageReview = reviewPointTotal / reviews.length;
return (
schema.beforeText +
' <span itemprop="name">' +
placeData.name +
"</span> " +
'<span itemprop="aggregateRating" itemscope="" itemtype="http://schema.org/AggregateRating">' +
'<span itemprop="ratingValue">' +
averageReview.toFixed(2) +
'</span>/<span itemprop="bestRating">5</span> ' +
schema.middleText +
' <span itemprop="ratingCount">' +
reviews.length +
"</span> " +
schema.afterText +
"</span>"
);
};
var generateSchemaItemMarkup = function (name, value) {
return '<meta itemprop="' + name + '" content="' + value + '">';
};
plugin.init();
};
$.fn.googlePlaces = function (options) {
return this.each(function () {
if (undefined == $(this).data(namespace)) {
var plugin = new $.googlePlaces(this, options);
$(this).data(namespace, plugin);
}
});
};
$("#google-reviews").googlePlaces({
placeId: locationPlaceId,
render: ["reviews"],
min_rating: 0,
max_rows: 100
});
$("#map-plug").remove();
$(window).load(function () {
var $slick = $('.testimonial-wrapper');
$slick.slick({
arrows: true,
autoplaySpeed: 4000,
autoplay: true,
dots: false,
infinite: true,
slidesToScroll: 1,
slidesToShow: 3,
adaptiveHeight: true,
centerMode: false,
responsive: [
{
breakpoint: 1024,
settings: {
arrows: false,
}
},
{
breakpoint: 800,
settings: {
slidesToShow: 3, slidesToScroll: 1, arrows: false,
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 1, slidesToScroll: 1, centerMode: true, centerPadding: '50px',
}
},
],
}).on("setPosition", function () {
if (!($(this).find('.slick-slide').length < 4)) {
$(this).parent().find(".slider-controls").removeClass("hidden");
}
$(this).find('.review-text').text(function (index, currentText) {
var maxLength = 650;
if (currentText.length >= maxLength) {
return currentText.substr(0, maxLength) + "...";
} else {
return currentText
}
});
$(".loading-reviews").hide();
equalizeElementHeights($(".review-text", this));
});
});
}
Updated on: 09/17/2024
Thank you!