Display Product Reviews

What We'll Cover

Anatomy of a product review

Product reviews are system messages, and can be found in the backend, "Customers > Messages". LemonStand helps you manage product reviews in your store control panel (see Managing Messages for more details), where you can approve, disapprove, or mark reviews as spam. The difference between a message and a review is that reviews are:

  • marked as a review in the contact form,
  • marked with a item_rating, which collects a whole number (0-5) for the rating,
  • related to the product with a shop_product_id,
  • and are related to the customer with a shop_customer_id (if they're logged in).

It is also possible to relate a product review to a specific variant or option, by providing summary text to the shop_item_summary field. This can be done with a dropdown of options that store visitors selects when authoring a review.

All system messages have a number of fields too. System messages include:

  • a title,
  • the customer's comment,
  • the customers name,
  • and the customer's email address.

LemonStand also tracks:

  • the customer's IP address,
  • and the store page they commented from

These automatic fields help in identifying spam, and for understanding where messages originate in your online store.

Overall product reviews

The overall product review, or review summary, includes a number of fields you can use in your product pages, including:

  • average rating as average,
  • total reviews as total_reviews,
  • the best rating as best_review,
  • the worst review as worst_review,
  • and the average_remainder to simplify showing overall star ratings

Collecting product reviews

You use a custom Contact Form partial or HTML to collect Product Reviews. The review form has a few additional fields, to mark it as a review, and to relate it to the product and customer:

Item ratings

The simplest way to get a product rating from a store visitor is using an HTML select element:

<select id="item_rating" name="fields[item_rating]">
    <option value="" diabled>-</option>
    <option value="1">★☆☆☆☆</option>
    <option value="2">★★☆☆☆</option>
    <option value="3">★★★☆☆</option>
    <option value="4">★★★★☆</option>
    <option value="5">★★★★★</option>
</select>

It's also possible to build a more interactive star rating control using JavaScript. As long as the JavaScript updates a hidden field before the form is posted, the rating will be included. A JavaScript will use a hidden field that looks like:

<input type="hidden" name="fields[item_rating]" value=""/>

Relating a review to a customer

To link a review to the current customer:

<input type="hidden" name="fields[shop_customer_id]" value="{{customer.id}}"/>

When this field is blank, the review will be anonymous.

Relating a review to the product

To link a review to the current product:

<input type="hidden" name="fields[shop_product_id]" value="{{product.id}}"/>

Other required fields

A review form must also include:

<input type="hidden" name="fields[message_type]" value="review"/>

Putting it all together

The completed Product Review form will look something like:

{{ flash() }}
{{ open_form({'data-ajax-handler': 'system:onSendMessage', 'data-test': 'true'}) }}
    <h3>Review this product</h3>
    <div class="row">
        <div class="twelve columns">
            <input type="text" id="contact_name" name="fields[name]" value="" placeholder="Your name"/>
            <span class="error"/>
        </div>
    </div>
    <div class="row">
        <div>
            <input type="text" id="contact_email" name="fields[email]" value="" placeholder="Email address"/>
            <span class="error"/>
        </div>
    </div>
    <div class="row">
        <div>
            <input type="text" id="subject" name="fields[subject]" value="" placeholder="Subject"/>
            <span class="error"/>
        </div>
    </div>
    <div class="row">
        <div>
            <textarea id="contact_message" name="fields[message]" value="" rows="10" placeholder="Your review"></textarea>
            <span class="error"/>
        </div>
    </div>
    <div class="row">
        <div>
        <select id="item_rating" name="fields[item_rating]">
            <option value="" diabled>-</option>
            <option value="1">★☆☆☆☆</option>
            <option value="2">★★☆☆☆</option>
            <option value="3">★★★☆☆</option>
            <option value="4">★★★★☆</option>
            <option value="5">★★★★★</option>
        </select>
            <span class="error"/>
        </div>
    </div>    
    <input type="submit" class="button" value="Submit"/>
    <input type="text" name="hp" value="" style="display: none"/>
    <input type="hidden" name="fields[shop_customer_id]" value="{{customer.id}}"/>
    <input type="hidden" name="fields[shop_product_id]" value="{{product.id}}"/>
    <input type="hidden" name="fields[message_type]" value="review"/>
{{ close_form() }}

Displaying product reviews

Showing all reviews

You can display product reviews by looping through the product.reviews() addition to the Product object. We recommend you put the review body itself in a partial, to keep your product partial tidy. You can also include your Product Review form partial in the same block of template:

<div class="reviews">
    <a id="reviews"></a>
    {% for review in product.reviews() %}
        {{ partial('shop-product-review', {'review': review, 'product': product } ) }}
    {% endfor %}
    {{ partial('shop-product-review-form', {'product': product, 'customer': customer } ) }}
</div>        

This list of reviews includes only approved reviews, allowing you to curate the reviews in your Product Catalog.

Including product reviews

Your product review partial can look something like:

<div itemscope itemtype="http://schema.org/Review">
  <div itemprop="itemReviewed" itemscope itemtype="http://schema.org/{{ product.productType }}">
    <span itemprop="name">{{ product.name }}</span>
  </div>
  <span itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating">
    <span itemprop="ratingValue">{{ review.rating }}</span>
  </span> stars -
  "<b><span itemprop="name">{{ review.title }}</span></b>"
  <span itemprop="author" itemscope itemtype="http://schema.org/Person">
    <span itemprop="name">{{ review.from_name }}</span>
  </span>
  <span itemprop="reviewBody">{{ review.comment }}</span>
</div>

This shows an example of a Product Review using standard Review markup. This is a great way to render reviews as crawlers like Google's understand it, and can display it as a review in their listings. This is great for increasing visibility into your store, for improving search rankings, and making it easier for customers to find products in your stores.

Including product review summaries

You can also show a summary of all reviews for a product (including its variants) by including a product rating block in your product partial:

{% set product_rating = product.rating() %}
<p>
{% if product_rating.total_reviews %}
{% for i in range(1, product_rating.average_int) %}★{% endfor %}
{% if product_rating.average_int != 5 %}{% for i in range(1, 5 - product_rating.average_int) %}☆{% endfor %}{% endif %}
 ({{product_rating.average}})
{% else %}
☆☆☆☆☆
 (- / 5)
{% endif %}
</p>
<p>
{% if product_rating.total_reviews %}
 <a href="#reviews">See all {{ product_rating.total_reviews }} reviews</a>
{% else %}
 <a href="#reviews">Add the first review</a>
{% endif %}
</p>    

This will display a summary block that include:

  • A star rating display and numeric representation
  • A link to the list of reviews on the page

Custom emails

Since the reviews are really just messages, these are sent to your Admin using the Contact Form Settings, found under "Administration > Contact Form".

You can also specify a custom email template, allowing you to customize the contents of the email sent to your admin:

<input type="hidden" name="template" value="system:product-review"/>

Here we would add a custom email template with the code:

system:product-review