Video icon 64
Learning to code? Skill up faster with our practical video courses. Start your free trial today.
Advertisement

Utilizing Custom Fields to Create Review Boxes

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

Reviews are perhaps one of the greatest powers of blogging in terms of authority. When done properly (with hard work and consistent information), review blogs are arguably the most profitable category in the blogosphere. But every blog has to offer a solid design in their posts, including reviews. In this post, we're going to talk about how to build the perfect review box, since review boxes are probably the first part readers check before reading a review.


What We're Going to Build

As an example, we're going to create a review box for a movie.

Let's take one of my favorite movies of all time, The Pursuit of Happyness. We're going to display the following information about the movie:

  • Name: The Pursuit of Happyness
  • Year: 2006
  • Director: Gabriele Muccino
  • Writer: Steve Conrad
  • Stars: Will Smith, Jaden Smith, Thandie Newton
  • Genre: Biography, Drama
  • Runtime: 117 minutes
  • Storyline: Based on a true story about a man named Christopher Gardner. Gardner has invested heavily in a device known as a "Bone Density scanner". He feels like he has made these devices. However, they do not sell as they are marginally better than the current technology at a much higher price. As Gardner tries to figure out how to sell them, his wife leaves him, he loses his house, his bank account, and credit cards. Forced to live out in the streets with his son, Gardner is now desperate to find a steady job; he takes on a job as a stockbroker, but before he can receive pay, he needs to go through 6 months of training, and to sell his devices.
  • (Let's not forget that we need an image.)

Important: This information is borrowed from The Internet Movie Database.


Step 1 Preparing the Custom Meta Box to Fill in the Data

We're going to hold the data as custom field values, but adding custom fields manually for each review can be such a pain. Because of that, we're going to create a neat custom meta box to save our data as custom fields.

First, we need to use the add_meta_box() function to build the meta box and create a callback function:

function wptuts_review_box_add_meta() {
	add_meta_box( 'review-box', 'The Review Box', 'wptuts_review_box_meta', 'post', 'normal', 'high' );
}
add_action( 'add_meta_boxes', 'wptuts_review_box_add_meta' );

function wptuts_review_box_meta() {
	// Hi there!
}

The callback function will create the input fields to hold our data. I think we can use a texarea for the "storyline" field and text input fields for everything else:

<?php
function wptuts_review_box_meta($post) {
    global $post;
    // get the custom field values (if they exist) as an array
    $values = get_post_custom( $post->ID );
    // extract the members of the $values array to their own variables (which you can see below, in the HTML code)
    extract( $values, EXTR_SKIP );
    wp_nonce_field( 'review_box_meta_action', 'review_box_meta_nonce' );
?>
    <p>
        <label for="review_name">Movie Name:</label>
        <input type="text" name="_wptuts_review_name" id="review_name" value="<?php echo $_wptuts_review_name[0]; ?>" />
    </p>
    <p>
        <label for="review_year">Year:</label>
        <input type="text" name="_wptuts_review_year" id="review_year" value="<?php echo $_wptuts_review_year[0]; ?>" />
    </p>
    <p>
        <label for="review_director">Director:</label>
        <input type="text" name="_wptuts_review_director" id="review_director" value="<?php echo $_wptuts_review_director[0]; ?>" />
    </p>
    <p>
        <label for="review_writer">Writer:</label>
        <input type="text" name="_wptuts_review_writer" id="review_writer" value="<?php echo $_wptuts_review_writer[0]; ?>" />
    </p>
    <p>
        <label for="review_stars">Stars:</label>
        <input type="text" name="_wptuts_review_stars" id="review_stars" value="<?php echo $_wptuts_review_stars[0]; ?>" />
    </p>
    <p>
        <label for="review_genre">Genre:</label>
        <input type="text" name="_wptuts_review_genre" id="review_genre" value="<?php echo $_wptuts_review_genre[0]; ?>" />
    </p>
    <p>
        <label for="review_runtime">Runtime:</label>
        <input type="text" name="_wptuts_review_runtime" id="review_runtime" value="<?php echo $_wptuts_review_runtime[0]; ?>" />
    </p>
    <p>
        <label for="review_image">Image:</label>
        <input type="text" name="_wptuts_review_image" id="review_image" value="<?php echo $_wptuts_review_image[0]; ?>" />
    </p>
    <p>
        <label for="review_storyline">Storyline:</label>
        <textarea name="_wptuts_review_storyline" id="review_storyline" cols="30" rows="10"><?php echo $_wptuts_review_storyline[0]; ?></textarea>
    </p>
<?php
}
?>

Then, we need to create the function to make WordPress save the input values as custom fields:

function wptuts_review_box_save_meta( $post_id ) {
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if( !isset( $_POST['review_box_meta_nonce'] ) || !wp_verify_nonce( $_POST['review_box_meta_nonce'], 'review_box_meta_action' ) ) return;
    if( !current_user_can( 'edit_post' ) ) return;
    // create an array of our custom fields
    $review_array = array(
        '_wptuts_review_name',
        '_wptuts_review_year',
        '_wptuts_review_director',
        '_wptuts_review_writer',
        '_wptuts_review_stars',
        '_wptuts_review_genre',
        '_wptuts_review_runtime',
        '_wptuts_review_image',
        '_wptuts_review_storyline'
    );
	// create the "default" values for the array
    $review_array_defaults = array(
        '_wptuts_review_name' => 'None',
        '_wptuts_review_year' => 'None',
        '_wptuts_review_director' => 'None',
        '_wptuts_review_writer' => 'None',
        '_wptuts_review_stars' => 'None',
        '_wptuts_review_genre' => 'None',
        '_wptuts_review_runtime' => 'None',
        '_wptuts_review_image' => 'None',
        '_wptuts_review_storyline' => 'None'
    );
	// parse 'em!
	$review_array = wp_parse_args($review_array, $review_array_defaults);
    // HTML elements that are allowed inside the fields
    $allowed_html = array(
        'a' => array(
            'href' => array(),
            'title' => array()
        ),
        'em' => array(),
        'strong' => array()
    );
    // update the post meta fields with input fields (if they're set)
    foreach($review_array as $item) {
        if( isset( $_POST[$item] ) )
            update_post_meta( $post_id, $item, wp_kses($_POST[$item], $allowed_html) );
    }
}
add_action( 'save_post', 'wptuts_review_box_save_meta' );

Done!

To find more information about creating custom meta boxes (and what these lines of code actually mean), you can read this fantastic article written by Christopher Davis and published on Wptuts+.

Step 2 Building the Function to Show the Review Box

Now that we covered how to set the information, we need to learn how to get the information. If you worked with custom fields before, this is going to be easy since we're just going to fetch custom field values.

WordPress has an easy-to-use function for getting custom field values:

$meta_values = get_post_meta($post_id, $key, $single);

We need to load custom field values into some HTML code, so it would be wise to think about the HTML now. I'm thinking something like this:

<div class="review-box">
	<img src="http://ourwebsite.com/uploads/the-pursuit-of-happyness.jpg" alt="The Pursuit of Happyness (2006)" class="review-box-image" />
	<ul class="review-box-list">
		<li><strong>Name:</strong> The Pursuit of Happyness</li>
		<li><strong>Year:</strong> 2006</li>
		<li><strong>Director:</strong> Gabriele Muccino</li>
		<li><strong>Writer:</strong> Steve Conrad</li>
		<li><strong>Stars:</strong> Will Smith, Jaden Smith, Thandie Newton</li>
		<li><strong>Genre:</strong> Biography, Drama</li>
		<li><strong>Runtime:</strong> 117 minutes</li>
		<li><strong>Storyline:</strong> Based on a true story about a man named Christopher Gardner. Gardner has invested heavily in a device known as a "Bone Density scanner". He feels like he has made these devices. However, they do not sell as they are marginally better than the current technology at a much higher price. As Gardner tries to figure out how to sell them, his wife leaves him, he loses his house, his bank account, and credit cards. Forced to live out in the streets with his son, Gardner is now desperate to find a steady job; he takes on a job as a stockbroker, but before he can receive pay, he needs to go through 6 months of training, and to sell his devices.</li>
	</ul>
</div>

And if we put them together, we'll have our function ready!

function wptuts_review_box() {
    global $post;
    // get the custom field values as an array
    $values = get_post_custom( $post->ID );
    // extract the members of the $values array to their own variables (which you can see below, in the HTML code)
    extract( $values, EXTR_SKIP );
    // if there's no image link in the "review_image" custom field, try to get the featured image
    if($_wptuts_review_image == '') {
        if(has_post_thumbnail()) {
            $get_wptuts_review_image = wp_get_attachment_image_src(get_post_thumbnail_id(), 'full');
            $_wptuts_review_image = $get_wptuts_review_image[0];
        } else {
            $_wptuts_review_image = 'http://placehold.it/150x200&text=No+Image';
        }
    }
	// escape the output, just in case
	$allowed_html = array(
		'a' => array(
			'href' => array(),
			'title' => array()
		),
		'em' => array(),
		'strong' => array()
	);
	$_wptuts_review_name_output = wp_kses($_wptuts_review_name[0], $allowed_html);
	$_wptuts_review_year_output = wp_kses($_wptuts_review_year[0], $allowed_html);
	$_wptuts_review_director_output = wp_kses($_wptuts_review_director[0], $allowed_html);
	$_wptuts_review_writer_output = wp_kses($_wptuts_review_writer[0], $allowed_html);
	$_wptuts_review_stars_output = wp_kses($_wptuts_review_stars[0], $allowed_html);
	$_wptuts_review_genre_output = wp_kses($_wptuts_review_genre[0], $allowed_html);
	$_wptuts_review_runtime_output = wp_kses($_wptuts_review_runtime[0], $allowed_html);
	$_wptuts_review_storyline_output = wp_kses($_wptuts_review_storyline[0], $allowed_html);
	$_wptuts_review_image_output = wp_kses($_wptuts_review_image[0], $allowed_html);
    $output = '<div class="review-box">
        <img src="'.$_wptuts_review_image_output.'" alt="'.$_wptuts_review_name_output.' ('.$_wptuts_review_year_output.')" class="review-box-image" />
        <ul class="review-box-list">
            <li><strong>Name:</strong> '.$_wptuts_review_name_output.'</li>
            <li><strong>Year:</strong> '.$_wptuts_review_year_output.'</li>
            <li><strong>Director:</strong> '.$_wptuts_review_director_output.'</li>
            <li><strong>Writer:</strong> '.$_wptuts_review_writer_output.'</li>
            <li><strong>Stars:</strong> '.$_wptuts_review_stars_output.'</li>
            <li><strong>Genre:</strong> '.$_wptuts_review_genre_output.'</li>
            <li><strong>Runtime:</strong> '.$_wptuts_review_runtime_output.'</li>
            <li><strong>Storyline:</strong> '.$_wptuts_review_storyline_output.'</li>
        </ul>
    </div>';
    return $output;
}

The CSS

Of course, you can style your review box any way you like. If you don't feel like it, you're welcome to use ours:

.review-box {width:550px;border:1px solid #DDD;border-radius:5px;margin:10px;}
.review-box-image {float:right;width:150px;border:10px solid #fff;border-width:0 0 10px 10px;margin:10px 10px 0 0;}
.review-box-list {margin:10px;padding:0;list-style:none;}
.review-box-list li {margin-bottom:5px;padding-top:5px;border-top:1px solid #EEE;}
.review-box-list li:first-child {border-top:0;}
.review-box-list li strong {display:inline-block;width:75px;}
If you want to float the review box to left or right, don't forget to add the float:left; (or float:right;) declaration for .review-box. You can even center it by changing the margin:10px; declaration into margin:10px auto;.

Step 3 Creating the Shortcode to Echo the Function

We know how to set the info, we know how to get the info... Now it's time that we show the info! :)

We can always add the box automatically at the end (or at the beginning) of the post like this:

function wptuts_review_box_add($content) {
	$review_box = wptuts_review_box();
	// show the box at the end of the post:
	return $content.$review_box;
	// show the box at the beginning of the post:
	// return $review_box.$content;
} add_action('the_content','wptuts_review_box_add');

But what if we want to include the box inside the post? That's where my favorite part comes in handy: shortcodes!

This step would be even easier than the previous one, since we actually done all the work to load the review box. All we have to do is call the function as a shortcode like this:

add_shortcode('reviewbox','wptuts_review_box');

Here's what you'll have if you follow the steps above exactly as they're written:

A screenshot of our example review box

Wrapping Up

These review boxes could be used for loads of different reviews like software, websites, books, TV shows and so on. Or, if you can get creative, you can even use them in regular blogs just to have fun!

Some Articles to Check

To fully understand the code and even to improve it, you should read some other articles of Wptuts+:

Is there anything you'd like to improve or do you have an idea? Share your thoughts with us by commenting below.

Advertisement