Create an SEO Friendly Customer Review System in WordPress


Posted in Search Engine Optimization (SEO), Web Development on October 26, 2017

Learn how to create a 5 star customer review system for Wordpress that can be used on any post type with full schema.org SEO support.

Employing a user-generated system helps boost user engagement and in turn, the rankings for your website. Customer reviews are one of the most important and potent forms of online user-generated content. Reviews play a massive part in influencing purchasing choices online.

I've spent the last several years building and developing database websites using WordPress. One website displayed a listing of local businesses. I wanted users to be able to leave a 1-5 star rating and a review of any business on the site.

I tried many plugins to get the job done, but none of the options out there did the trick. They all had too many features, limited features, poor customization options or bloated code.

Without a plug and play solution, I ended up developing my own customer review solution. I'm here today to share that solution with you.

The resulting system allowed me to collect, moderate and display user-generated reviews on my website. The features include:

  • Review Submit Form
  • Submission Moderation
  • 1-5 Star Ratings with Title and Comments
  • SEO Friendly Schema.org Markup
  • Custom Review Fields & Display
  • Works with Posts, Pages, or Custom Post Types

This post will help you implement the same review system on your website.

Our Example Implementation

This review system can be implemented and customized in various ways. To keep things simple, and focus primarily on the review system itself, we are going to be displaying these reviews on WordPress's standard posts type.

It is likely that you'd want to implement this same functionality on something like a custom post type driven database or perhaps Woocommerce products. The same fundamentals apply in these cases. Simply perform the same actions on your custom post type rather than on the standard posts.

Tools You'll Need

In order to get the system up and running, you will need the following:

  • Reviews Custom Post Type
    • The collected reviews will live in a custom post type in WordPress. I'll guide you through the creation of this plugin in the next section below.
  • Advanced Custom Fields
    • ACF allows us to add the required fields to the review post type as well as create a relationship between a review and a post, page, or custom post type. This is a great plugin and the free version will do the trick for our needs.
  • Gravity Forms
    • This form plugin will allow us to collect reviews on the front end and send them into the reviews custom post type. Again, this is a solid WordPress plugin that I highly recommend.

The following setup can also be accomplished by substituting Advanced Custom Fields for WP-Type's Toolset using Types. This can be helpful if you're already developing your website in Toolset using Views, Types, and CRED.

Create the Review Custom Post Type

The first step in our process is to create a custom post type that will hold the visitor reviews. We will write a quick plugin that does just this.

It is important to note that this review post type is not visible from the front end of the site. In other words, you won't be able to visit an individual review. We do this because we want to display the reviews on the related pages.

You'll want to ensure that this post type is omitted from your website's sitemap. In Yoast's SEO plugin you can do this under SEO > XML Sitemaps > Post Types

The following code makes up our plugin. It declares the post type and sets the appropriate settings:

<?php
/*
Plugin Name: Review Custom Post Types & Taxonomies
Plugin URI: 
Description: Declares a plugin that create's a custom post type named Reviews.
Version: 1.0
Author: Vince Arnone
Author URI: https://netmospherics.com/
*/

function reviews_post_type() {

	$labels = array(
		'name'                  => _x( 'Reviews', 'Post Type General Name', 'text_domain' ),
		'singular_name'         => _x( 'Review', 'Post Type Singular Name', 'text_domain' ),
		'menu_name'             => __( 'Reviews', 'text_domain' ),
		'name_admin_bar'        => __( 'Reviews', 'text_domain' ),
		'archives'              => __( 'Reviews Archives', 'text_domain' ),
		'attributes'            => __( 'Reviews Attributes', 'text_domain' ),
		'parent_item_colon'     => __( 'Parent Reviews:', 'text_domain' ),
		'all_items'             => __( 'All Reviews', 'text_domain' ),
		'add_new_item'          => __( 'Add New Review', 'text_domain' ),
		'add_new'               => __( 'Add New', 'text_domain' ),
		'new_item'              => __( 'New Review', 'text_domain' ),
		'edit_item'             => __( 'Edit Review', 'text_domain' ),
		'update_item'           => __( 'Update Review', 'text_domain' ),
		'view_item'             => __( 'View Review', 'text_domain' ),
		'view_items'            => __( 'View Reviews', 'text_domain' ),
		'search_items'          => __( 'Search Review', 'text_domain' ),
		'not_found'             => __( 'Not found', 'text_domain' ),
		'not_found_in_trash'    => __( 'Not found in Trash', 'text_domain' ),
		'featured_image'        => __( 'Featured Image', 'text_domain' ),
		'set_featured_image'    => __( 'Set featured image', 'text_domain' ),
		'remove_featured_image' => __( 'Remove featured image', 'text_domain' ),
		'use_featured_image'    => __( 'Use as featured image', 'text_domain' ),
		'insert_into_item'      => __( 'Insert into Review', 'text_domain' ),
		'uploaded_to_this_item' => __( 'Uploaded to this Review', 'text_domain' ),
		'items_list'            => __( 'Items list', 'text_domain' ),
		'items_list_navigation' => __( 'Items list navigation', 'text_domain' ),
		'filter_items_list'     => __( 'Filter items list', 'text_domain' ),
	);
	$rewrite = array(
		'slug'                  => 'reviews',
		'with_front'            => false,
		'pages'                 => false,
		'feeds'                 => false,
	);
	$args = array(
		'label'                 => __( 'Review', 'text_domain' ),
		'description'           => __( 'Profiles for Reviews', 'text_domain' ),
		'labels'                => $labels,
		'supports'              => array( 'title'),
		'hierarchical'          => true,
		'public'                => true,
		'show_ui'               => true,
		'show_in_menu'          => true,
		'menu_position'         => 45,
		'menu_icon'             => 'dashicons-star-filled',
		'show_in_admin_bar'     => true,
		'show_in_nav_menus'     => true,
		'can_export'            => true,
		'has_archive'           => false,		
		'exclude_from_search'   => true,
		'publicly_queryable'    => true,
		'rewrite'               => $rewrite,
		'capability_type'       => 'page',
	);
	register_post_type( 'reviews', $args );

}
add_action( 'init', 'reviews_post_type', 0 );

?>

The above code needs to be saved in a .php file in a folder. Name the folder 'review-custom-post-type' and the PHP file the same 'review-custom-post-type.php'. This folder with the PHP file in it will be uploaded as a new plugin to your WordPress install and end up living in /wp-content/plugins/.

I've packaged the plugin and saved it as a .zip file for you to download.

Once you enable the plugin, you'll see the new reviews post type show up in the sidebar of your WP admin.

Reviews Custom Post Type in WordPress Admin

Configuring the Review Fields

The next thing we need to do is create the required fields using ACF. We will create all the fields

To create these fields, navigate to the ACF 'Custom Fields' menu item in the WordPress admin. You'll land on a page titled Field Groups. From here, click the Add New button.

Name the group something like Reviews - Fields. Next, we need to add the following custom fields to the Review post type.

  • Review Post (Relationship)
  • Nickname (Text)
  • Email (Email)
  • Star Rating (Number - set the minimum value to 0 and maximum value to 5)
  • Title (Text)
  • Content (Text Area)

All the fields are straightforward, but the post-relationship needs a bit more explaining. This field is used to set a relationship between a review and a post. In simple terms, this review belongs to this post.

In order to accomplish this, you'll set the field type to relationship and filter by post type to post. You can then check search under the filters setting area to enable a type to search function.

Relationship Post Type Configuration

Click to View Full Size

Remember that in this example we are reviewing posts, but if you were reviewing something else like a custom post type you created, you'd want to associate this relationship with your custom post type.

Finally, scroll down to the Location section. Here, we will set the field display rules to show if the post type is equal to review. The end result will look like this:

Complete Review Custom Field Setup

Click to View Full Size

Once you've completed this configuration and saved the field group, navigate to Reviews > Add New. Here you'll see all the fields we just created displaying in the entry screen for a new review:

Review Custom Fields Result

Click to View Full Size

Implement the Review Calculation Logic

The next thing we need to do is create 3 pieces of logic. By placing some PHP code in our functions.php, we will accomplish the following:

  • Calculate the average rating of all reviews for a given post.
  • Calculate and round the average rating to the nearest .5 for a given post.
  • Count the total number of reviews for a given post.

Copy and paste the following code into your theme's functions.php file:

//Calculates and returns the average rating of a post's reviews.
function rating_average_func()
{
    $reviews = get_posts(array(
        'post_type' => 'reviews',
        'posts_per_page'   => -1,
        'meta_query' => array(
            array(
                'key' => 'review_post', // name of custom field
                'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
                'compare' => 'LIKE'
            )
        )
    ));
       
    $sum = 0;
    $num = 0;
    foreach ($reviews as $review) {
        $rating = get_field('star_rating', $review->ID);
        if(isset($rating))
        {
            $sum += $rating;
            $num ++;
        }
    }
    $average = 0;
    if($num>0)
    {
        $average = $sum/$num;
    }
    $res = $average;
    $resfin = round($res,1);
    return $resfin;
}

//Calculates and returns the average rating of a post's reviews rounded to the nearest .5
function rating_average_rounded_func()
{
    $reviews = get_posts(array(
        'post_type' => 'reviews',
        'posts_per_page'   => -1,
        'meta_query' => array(
            array(
                'key' => 'review_post', // name of custom field
                'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
                'compare' => 'LIKE'
            )
        )
    ));
       
    $sum = 0;
    $num = 0;
    foreach ($reviews as $review) {
        $rating = get_field('star_rating', $review->ID);
        if(isset($rating))
        {
            $sum += $rating;
            $num ++;
        }
    }
    $average = 0;
    if($num>0)
    {
        $average = $sum/$num;
    }
    $res = $average;
    $resfin = round($res*2) / 2;
    return $resfin;
}

//Calculates and returns the number of reviews associated with a given post
function reviews_total_func()
{
$review_total = get_posts(array(
    'post_type' => 'reviews',
    'posts_per_page'   => -1,
    'meta_query' => array(
        array(
            'key' => 'review_post', // name of custom field
            'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
            'compare' => 'LIKE'
        )
    )
));
return count($review_total);
}

Note: If you've followed the guide exactly up to this point, then take note that the post type, meta query key, and star rating fields are all set appropriately. If you chose different names for these values, you may need to adjust them in the code below. See 'reviews', 'review_post', and 'star_rating' as they relate to the configuration we did in the step above.

Create Some Test Data

Before we get to creating the front end display, we need a bit of test data to proceed. Head into the admin and create a test post that you'll be reviewing. Once you have that test post, go through the admin to the reviews post type and enter a few example reviews.

I suggest entering different ratings in each of the reviews you create. This will enable us to test the average rating and rounded average rating functions.

Now that we have some test data, let's display it on the front end!

Create the Front-End Display

At this point, the backend review system is complete! Next, we will put together the front end display for the reviews. This bit of code will live on the page.php template file in your theme or child theme. Remember, if you're adding reviews to a custom post type, this code will go into the template file for that post type. Adjust as needed.

Test Review Display

We are going to break up this display implementation into 3 parts. The end result will display an aggregate rating system, followed by a loop that displays each review. All of the following code uses inline schema.org implementation which will enable these reviews to display alongside your page's organic search result.

Pre-Load Review Values

First, we need to grab the information from the review calculation logic we did in the step before. This will load 3 numeric values into PHP variables. The 3 numbers are:

  • The total number of reviews for the post.
  • The average rating.
  • The average rating rounded to the nearest .5.

The following code will go at the top of the post.php template, just under the get_header(); call:

<?php
// Grab review values for the current post.
$numreviews = reviews_total_func();
$avgrating = rating_average_func();
$avgratingrounded = rating_average_rounded_func();
?>

Review Aggregate Rating Section

Now that we have the above values, we can begin to build the logic that displays the aggregate review section. This is the short review display that usually appears at the top of the page, giving a user a snapshot of that page's overall rating.

You can see in the code below that first the code checks if the number of reviews is 0 and then display's the correct data depending on the result. If there are reviews to display, all the appropriate Schema.org tags are implemented.

In our case, we've also linked it using an anchor down to the review section lower on the page. It's common practice to place the actual reviews near the bottom of the page, this link helps users quickly jump down the page to read individual reviews.

<!-- Review Aggregate Section -->
<?php if($numreviews == 0) { ?>
	<a href="#reviews"><div class="star-rating large-stars-0"></div></a> <a href="#reviews">No Reviews</a>
<?php } else { ?>
	<span itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
		<a href="#reviews"><div class="star-rating large-stars-<?php echo str_replace(".","-",$avgratingrounded); ?>"></div></a><a href="#reviews"><?php echo $numreviews; ?> Reviews</a>
		<meta itemprop="ratingValue" content="<?php echo $avgrating; ?>" />
    	<meta itemprop="reviewCount" content="<?php echo $numreviews; ?>" />
	</span>
<?php } ?>

Looping Through Individual Reviews

Next, we need to loop through and display each individual review. The following code does a few things:

  1. It set's the title of the section and provides the HTML anchor (id="reviews") for the aggregate rating to land on.
  2. If there are reviews to display, it displays a summary of the reviews to come.
  3. If there are reviews to display, loops through each individual review. During this, all the review information is displayed and the Schema tags are applied.

This bit of code will sit further down the page, wherever you'd like your reviews to display. There is minimal formatting on the code below, so you'll probably end up styling it a bit for your needs.

<!-- Individual Reviews Loop -->
<h2 id="reviews">Reviews</h2>

<?php if($numreviews != 0) { ?>
	<b>Rated an average of <?php echo $avgrating; ?> out of 5 stars by <?php echo $numreviews; ?> reviewers.</b>
<?php } ?>

<?php
// Pull all the related review entries for the current post.
$reviews = get_posts(array(
	'posts_per_page'   => -1,
	'meta_query' => array(
		array(
			'key' => 'review_post', // name of custom field
			'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
			'compare' => 'LIKE'
		)
	)
));

// If there are reviews to show, get the information for each review and loop through the display
if( $reviews ): foreach( $reviews as $review ):
		$reviewrating = get_field('star_rating', $review->ID);
		$reviewtitle = get_field('review_title', $review->ID);
		$reviewcontent = get_field('review_content', $review->ID);
		$reviewernickname = get_field('nickname', $review->ID);
		?>
		<div itemprop="review" itemscope itemtype="http://schema.org/Review">
			<div itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating">
				<meta itemprop="worstRating" content="1" />
				<meta itemprop="bestRating" content="5" />
				<meta itemprop="ratingValue" content="<?php echo $reviewrating; ?>" />
		    </div>
		    	<b>"<span itemprop="name"><?php echo $reviewtitle; ?></span>"</b> by <span itemprop="author"><?php echo $reviewernickname; ?></span><br />
				<div class="star-rating small-stars-<?php echo $reviewrating; ?>"></div> on <meta itemprop="datePublished" content="<?php echo get_the_date('Y-m-d'); ?>"><?php echo get_the_date(); ?><br />
				<span itemprop="description"><?php echo $reviewcontent; ?></span>
			<hr />
		</div>
	<?php endforeach; ?>

	<?php wp_reset_postdata(); ?>

<?php else : ?>
	<p>There are no reviews to display.</p>
<?php endif; ?>

Enabling the Star Display with CSS Sprites

If you've followed along this far, you'll see that the review display is almost complete - but stars are missing! The last step in the front end display is to add the PNG sprite images and the CSS code that drives the display.

In this system, I've created two sized of stars for your use. You can see that I've used the larger stars in the aggregate section, and the smaller in the individual review display.

Rating Stars Sprite

You'll need to download the above sprite. This image will live on your site. You can see in the first .star-rating CSS declaration below that I've put an example URL in your site's theme.

Upload this image wherever you'd like it to live and adjust the background URL value to point at the sprite. Then add the following code to your theme's main CSS file. This code drives the star display in the implementation code in this section. There are also a couple lines in there to drive the display on the submission form in the next section.

After you add these final display elements, do a hard refresh on your test page to ensure the display is good to go!

/* ------------------------------------- Star Rating Styles ------------------------------------- */
.star-rating {
background: url(/wp-content/themes/your-theme/rating-stars.png) no-repeat;
background-size: 132px 420px;
display: inline-block;
vertical-align: middle;
margin-right:.5rem;
}
.large-single-star-inactive {
width: 24px;
height: 24px;
background-position: 0 0;
}
.large-single-star-active {
width: 24px;
height: 24px;
background-position: 0 -24px;
}
.large-stars-0 {
width: 132px;
height: 24px;
background-position: 0 0;
}
.large-stars-1 {
width: 132px;
height: 24px;
background-position: 0 -24px;
}
.large-stars-1-5 {
width: 132px;
height: 24px;
background-position: 0 -48px;
}
.large-stars-2 {
width: 132px;
height: 24px;
background-position: 0 -72px;
}
.large-stars-2-5 {
width: 132px;
height: 24px;
background-position: 0 -96px;
}
.large-stars-3 {
width: 132px;
height: 24px;
background-position: 0 -120px;
}
.large-stars-3-5 {
width: 132px;
height: 24px;
background-position: 0 -144px;
}
.large-stars-4 {
width: 132px;
height: 24px;
background-position: 0 -168px;
}
.large-stars-4-5 {
width: 132px;
height: 24px;
background-position: 0 -192px;
}
.large-stars-5 {
width: 132px;
height: 24px;
background-position: 0 -216px;
}
.small-stars-0 {
width: 100px;
height: 18px;
background-position: 0 -240px;
}
.small-stars-1 {
width: 100px;
height: 18px;
background-position: 0 -258px;
}
.small-stars-1-5 {
width: 100px;
height: 18px;
background-position: 0 -276px;
}
.small-stars-2 {
width: 100px;
height: 18px;
background-position: 0 -294px;
}
.small-stars-2-5 {
width: 100px;
height: 18px;
background-position: 0 -312px;
}
.small-stars-3 {
width: 100px;
height: 18px;
background-position: 0 -330px;
}
.small-stars-3-5 {
width: 100px;
height: 18px;
background-position: 0 -348px;
}
.small-stars-4 {
width: 100px;
height: 18px;
background-position: 0 -366px;
}
.small-stars-4-5 {
width: 100px;
height: 18px;
background-position: 0 -384px;
}
.small-stars-5 {
width: 100px;
height: 18px;
background-position: 0 -402px;
}

Create the Submit a Review Form

At this point, we have a fully functioning review system. There is only one problem - we need a way for users to submit reviews!

Submit a Review Form Example

We will use Gravity Forms to create this submission form. To make things easier to admin, this form will gather user data, email the moderator(s) and automatically create the review post in the backend. All you'll need to do is publish reviews as they come in.

Create the Submission Form in Gravity Forms

With Gravity Forms installed, head to the WordPress admin. Navigate to Forms > New Form and enter a name like "Review: Submit".  You're going to create a series of form elements that collect data from the user and some field information that we will pass via the review link URL.

I've listed the following fields below with screenshots showing the details of how to configure each field. Note that all of the non-hidden fields are using a 'custom field' type. This is so we can automatically load this information into the corresponding ACF custom field that we created earlier.

Rating Field

This custom field requires the most configuration of all. We create a radio list with 1-5 to collect the rating. We then set the CSS class to 'js-gf-rating-stars' which we will use in the template. This allows us to style this field to display as a hoverable and clickable star rating select.

Your Rating Tab 1

Click to Open Full Size

Your Rating Tab 2

Click to Open Full Size

Your Rating Tab 3

Click to Open Full Size

Title Field

Title Field

Click to Open Full Size

Review Content Field

Your Review Field

Click to Open Full Size

Nickname Field

Nickname Field

Click to Open Full Size

Email Field

Email Field

Click to Open Full Size

Post Name Field

Post Name Hidden Field

Click to Open Full Size

Post URL Field

Post URL Hidden Field

Click to Open Full Size

Submission Date Field

Submission Date Hidden Field

Click to Open Full Size

Now that you've created all the required fields, you can configure the confirmations and notifications under this form's settings. Here you'll be able to set the message that appears after the form is submitted. You can also

Programmatically Submit & Set the Title of the Review

As a user submits this form, we need to configure Gravity Forms to create a review custom post type entry for the submission. In order to better organize our submissions, we need to set the title dynamically as it is submitted.

To do this, the following code needs to be added to your theme's functions.php file:

//Submits reviews to the review custom post type and sets a title
add_filter( 'gform_post_data', 'change_post_type', 10, 3 );      
function change_post_type( $post_data, $form, $entry ) {
    //Change the ID from 1 to the ID of your Gravity Forms post ID if need be.
    if ( $form['id'] != 1 ) {
       return $post_data;
    }
    // Sets the title of the review to "Post Name - Submission Date"
    // Change the following ID's to your Post Name and Submission date field IDs
    $title = rgar( $entry, '7' ) . ' - ' . rgar( $entry, '9' );

    $post_data['post_type'] = 'reviews';
    $post_data['post_title'] = $title;
    return $post_data;
}

Create the Review Collection Page & Template

Now that we have the form and logic behind it, it's time to create the review page and the template that drives it.

Start by creating a new page in WordPress. I've created a page titled "Submit a Review" with the slug: submit-a-review. The page doesn't need any content. We will drive the page by using a template file. Grab the following code and save it as a WordPress page template named page-submit-a-review.php:

<?php get_header(); ?>

<?php
$name = isset( $_GET['postname'] ) ? esc_attr( $_GET['postname'] ) : '';
$url = isset( $_GET['posturl'] ) ? esc_attr( $_GET['posturl'] ) : '';
?>

<!-- Slightly modified Gravity Forms clickable star rating list item. Source: https://gist.github.com/taeo/3ae264fa4aad3463b26f -->

<script>
(function($) {
    $(document).ready(function() {
        $('.js-gf-rating-stars').gformsRatings();
    });
    // The meat and potatoes
    $.fn.gformsRatings = function( options ) {
        // Setup options
        var settings = $.extend({
            'labels' : false,
            'activeClass' : 'large-single-star-active',
            'iconClass' : 'star-rating large-single-star-inactive'
        }, options);
        return this.each(function() {
            // Store the object
            var $this = $(this),
                $container = $('.ginput_container', $this),
                $radioGroup = $('.gfield_radio', $this),
                $radios = $('input[type="radio"]', $radioGroup),
                $stars = null,
                $currentIndex = null;
            // Initialize
            var init = function() {
                $radioGroup.css('display', 'none');
                $wrap = $('<div class="gf-rating-stars"></div>');
                for (var i = 0; i < $radios.length; i++) {
                    var label = $radios.eq(i).siblings('label').text(),
                        value = $radios.eq(i).val(),
                        $star = $('<i class="js-gf-rating-star"></i>');
                    $star
                        .addClass(settings.iconClass)
                        .data('index', i)
                        .data('value', value)
                        .data('label', label)
                        .attr('title', label)
                        .appendTo($wrap);
                }
                $wrap.appendTo($container);
                
                $stars = $('.js-gf-rating-star');
                // Star Interactions
                $stars.on('hover', function() {
                    handleHover($(this));
                }).on('click', function() {
                    handleClick($(this));
                });
                // Restore to currently checked next field
                $wrap.on('mouseout', function() {
                    $checked = $radios.filter(':checked');
                    if (!$checked.length) {
                        $stars.removeClass(settings.activeClass);
                    } else {
                        highlight($currentIndex);
                    }
                });
            }
            var highlight = function(index) {
                $stars.filter(':gt(' + index + ')').removeClass(settings.activeClass);
                $stars.filter(':lt(' + index + '), :eq(' + index + ')').addClass(settings.activeClass);
            }
            var handleHover = function(el) {
                var index = el.data('index');
                highlight(index);
            }
            var handleClick = function(el) {
                var index = el.data('index');
                $currentIndex = index;
                $radios.eq(index).trigger('click');
            }
            // Kick it off
            init();
        });
    };
})(jQuery);
</script>

<div>
	<h1><?php the_title(); ?> for <?php echo $name; ?></h1>
    <p>Please use the form to submit a review. You may also return to <a href="<?php echo $url; ?>"><?php echo $name; ?></a></p>

	<?php
		if(isset($_GET['postname']))
		{
		// Replace '1' with the ID of your review submission form.
		gravity_form( 1, false, false, false, '', true);
		} else {
		echo 'Please visit any page and click the leave a review button to leave your feedback.';
	} ?>
</div>

<?php get_footer(); ?>

The template code does a few things:

  • It grabs two URL parameters that we will set in the review link.
  • A nice piece of Javascript by Taeo styles our radio select field as a clickable star rating selector.
  • If the URL parameters are set, the review form is called.

Create the Review Link

The last piece of the puzzle is a simple one: we need to create the link to the review form.

This link will live in our post template. The link sends a user to the review form page with two dynamically populated URL parameters. These parameters pass the post title and URL over to our form. Our form captures these pieces of data and passes them along with the review. You'll use these pieces of information as you moderate each new review and set the related post.

Use the following code in your page template where you want to provide a link to leave a review:

<a href="/submit-a-review/?postname=<?php echo get_the_title(); ?>&posturl=<?php echo get_permalink(); ?>">Leave a Review</a>

Round Trip Test

The last step is to do a complete round trip test of your system! Head over to a page without any reviews and check out the display. Click into your new form, leave a review, approve it, and test the display. Your new system should be all functional.

This system is wide open for all kinds of interesting tweaks. I've given you a framework that can be expanded as you need. If you have any questions, leave them in the comments below and I will answer them.


Share:

Subscribe for the latest posts delivered directly to your inbox.

Don't miss an update!

Related Posts


Leave a Reply

Your email address will not be published. Required fields are marked *