Articles on: coreFORCE Advanced & Enterprise

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

<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.
https://developers.google.com/maps/documentation/javascript/examples/places-placeid-finder#maps_places_placeid_finder-javascript

$(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 + "&nbsp;</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

Was this article helpful?

Share your feedback

Cancel

Thank you!