Beginner's Guide for WordPress - Start your WordPress Blog in minutes.
Choosing the Best
WordPress Hosting
How to Easily
Install WordPress
Recommended
WordPress Plugins
View all Guides

How to Add Rotating Testimonials in WordPress

Last updated on by
Elegant Themes
How to Add Rotating Testimonials in WordPress

Recently, we had to create a rotating testimonials display in WordPress for one of our clients. We did a brief search on the web, but we did not find a plugin that did what we wanted. Rather than spending a lot of time finding the right plugin, we decided to create this from scratch. In this article, we will show you how you can create a rotating testimonials area in WordPress where testimonials fade in and out automatically. You can use this technique for other uses as well such as quotes, fun facts, etc.

Note: You need to have a fair understanding of how WordPress work in order to follow this tutorial.

The approach we took was like this: Register a custom post type and call it Testimonials. We wanted to show information like: Client’s name, their position in the company, company name, and link to our portfolio page. Instead of using custom fields, we decided to add a custom meta boxes to make it easy for our client to enter the information. Last but certainly not least, add JavaScript fadeIn and fadeOut to rotate the testimonials on the same page. Obviously it is hard to show a live demo of it on this page, but if you know how fadeIn and fadeOut works, then you get the point.

Step 1: Register a Custom Post Type

We won’t go in lengthy explanation of how to create a Custom Post Type. We have already written an article about creating custom post types in WordPress. That article has a video that will explain the process. It also shows the plugin method rather than the hard code method. Now if you want to call your custom post type “Testimonials”, then all you have to do is paste the following code in your theme’s functions.php file.

add_action( 'init', 'wpb_register_cpt_testimonial' );

function wpb_register_cpt_testimonial() {

    $labels = array( 
        'name' => _x( 'Testimonials', 'testimonial' ),
        'singular_name' => _x( 'testimonial', 'testimonial' ),
        'add_new' => _x( 'Add New', 'testimonial' ),
        'add_new_item' => _x( 'Add New testimonial', 'testimonial' ),
        'edit_item' => _x( 'Edit testimonial', 'testimonial' ),
        'new_item' => _x( 'New testimonial', 'testimonial' ),
        'view_item' => _x( 'View testimonial', 'testimonial' ),
        'search_items' => _x( 'Search Testimonials', 'testimonial' ),
        'not_found' => _x( 'No testimonials found', 'testimonial' ),
        'not_found_in_trash' => _x( 'No testimonials found in Trash', 'testimonial' ),
        'parent_item_colon' => _x( 'Parent testimonial:', 'testimonial' ),
        'menu_name' => _x( 'Testimonials', 'testimonial' ),
    );

    $args = array( 
        'labels' => $labels,
        'hierarchical' => false,
        
        'supports' => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'custom-fields', 'revisions' ),
        
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        
        
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => true,
        'capability_type' => 'post'
    );

    register_post_type( 'testimonial', $args );
}

Step 2: Adding Custom Meta Boxes

As explained earlier, the information we wanted to display included:

  • Person’s Name who is giving the Testimonial
  • Their position in the Company
  • Company Name
  • Link to the company page on our Portfolio
  • Testimonial test (which will be the post body)

Now you can go and use custom fields if you like, but we prefer to have a nicer display that makes it easy for anyone to enter the information. The code we used to add the meta box goes like this: (Note: you would need to paste this in your theme’s functions.php file)

$key = "testimonial";
$meta_boxes = array(
"person-name" => array(
"name" => "person-name",
"title" => "Person's Name",
"description" => "Enter the name of the person who gave you the testimonial."),
"position" => array(
"name" => "position",
"title" => "Position in Company",
"description" => "Enter their position in their specific company."),
"company" => array(
"name" => "company",
"title" => "Company Name",
"description" => "Enter the client Company Name"),
"link" => array(
"name" => "link",
"title" => "Client Link",
"description" => "Enter the link to client's site, or you can enter the link to your portfolio page where you have the client displayed.")
);
 
function wpb_create_meta_box() {
global $key;
 
if( function_exists( 'add_meta_box' ) ) {
add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Information', 'display_meta_box', 'testimonial', 'normal', 'high' );
}
}
 
function display_meta_box() {
global $post, $meta_boxes, $key;
?>
 
<div class="form-wrap">
 
<?php
wp_nonce_field( plugin_basename( __FILE__ ), $key . '_wpnonce', false, true );
 
foreach($meta_boxes as $meta_box) {
$data = get_post_meta($post->ID, $key, true);
?>
 
<div class="form-field form-required">
<label for="<?php echo $meta_box[ 'name' ]; ?>"><?php echo $meta_box[ 'title' ]; ?></label>
<input type="text" name="<?php echo $meta_box[ 'name' ]; ?>" value="<?php echo htmlspecialchars( $data[ $meta_box[ 'name' ] ] ); ?>" />
<p><?php echo $meta_box[ 'description' ]; ?></p>
</div>
 
<?php } ?>
 
</div>
<?php
}
 
function wpb_save_meta_box( $post_id ) {
global $post, $meta_boxes, $key;
 
foreach( $meta_boxes as $meta_box ) {
$data[ $meta_box[ 'name' ] ] = $_POST[ $meta_box[ 'name' ] ];
}
 
if ( !wp_verify_nonce( $_POST[ $key . '_wpnonce' ], plugin_basename(__FILE__) ) )
return $post_id;
 
if ( !current_user_can( 'edit_post', $post_id ))
return $post_id;
 
update_post_meta( $post_id, $key, $data );
}
 
add_action( 'admin_menu', 'wpb_create_meta_box' );
add_action( 'save_post', 'wpb_save_meta_box' );

Now if you go and try to add a New Testimonial, you will have a custom meta box like the one in the image below:

Testimonial Meta Box

If you want to add additional fields to the meta boxes, you can simply add them into the $meta_boxes = array(. If you don’t understand the code above, but still want to add additional fields, then perhaps you should consider using a plugin called More Fields (Video Tutorial).

Step 3. Displaying the Rotating Content

First thing we need to do is add the JavaScript that will rotate the content.

<script language="javascript"> 
$(document).ready(function(){
	$('#testimonials .slide');
	setInterval(function(){
		$('#testimonials .slide').filter(':visible').fadeOut(1000,function(){
			if($(this).next('.slide').size()){
				$(this).next().fadeIn(1000);
			}
			else{
				$('#testimonials .slide').eq(0).fadeIn(1000);
			}
		});
	},15000);	
});	
</script>

Make sure that jQuery is being loaded in the header already. If it is not, then you would need to add that as well.

Next we will create the loop that will display the testimonials. The code we used is below:

<div id="testimonials">
<?php
$args = array( 'post_type' => 'testimonial', 'posts_per_page' => 10 );
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();
$data = get_post_meta( $loop->post->ID, 'testimonial', true );
static $count = 0;
if ($count == "1") { ?>



<div class="slide" style="display: none;">
<div class="client-contact-info"><?php echo $data[ 'person-name' ]; ?>,&nbsp;<?php echo $data[ 'position' ]; ?>,&nbsp;<a href="<?php echo $data[ 'link' ]; ?>" title="<?php echo $data[ 'company' ]; ?>"><?php echo $data[ 'company' ]; ?></a></div>
<div class="clear"></div>
<div class="testimonial-quote"><?php the_content(); ?></div>
</div>
<?php }
else { ?>


<div class="slide">
<div class="client-contact-info"><?php echo $data[ 'person-name' ]; ?>,&nbsp;<?php echo $data[ 'position' ]; ?>,&nbsp;<a href="<?php echo $data[ 'link' ]; ?>" title="<?php echo $data[ 'company' ]; ?>"><?php echo $data[ 'company' ]; ?></a></div>
<div class="clear"></div>
<div class="testimonial-quote"><?php the_content(); ?></div>
</div>

<?php 
$count++; } 
endwhile; 
endif; ?>
</div>

You would need to paste the above code anywhere you want to display the testimonial. Whether it is on your homepage, custom page template, sidebar, or footer. Pick a place and paste the code.

A little explanation to why this loop is a bit more complicated then a normal loop. First thing we do is tell the loop that we want to pull posts from the post type “testimonial”. Next thing we tell it is that only show 10 recent testimonials. The way our JavaScript works is that we need to only show the first post. The other 9 has to be invisible, so it can fadein and fadeout.

Now once you have pasted the code above, you need to style it.

#testimonials{}
#testimonials .slide{color: #9c968e;}
#testimonials .client-contact-info{margin: 25px 0 0 0; float: left;}
#testimonials .testimonial-quote{padding: 3px 0 0 65px; line-height: 1.5em; font-family: "proxima-nova-1", "proxima-nova-2", Helvetica, Arial, sans-serif !important; font-size: 16px; font-weight: normal; font-style: italic; margin: 10px 0 20px 0;}

Now the output of our code will look like this:

Client Name, Their Position in the Company, Company Name (hyperlinked)
Testimonial Text

Example:

Syed Balkhi, Founder, WPBeginner
This quote this is pretty cool.

Few things to note in the tutorial, if you do add additional fields, you will have to add it to the loop. You can change the styling however you want.

Because this thing is very specific, we thought it was not worth releasing a plugin for it. However, if you are looking to do the exact same thing we did, and want to have the exact same display that we have, then you are in luck.

Simply create a new file and call it testimonials.php and save it in your plugin’s folder (/wp-content/plugins/). Then paste the following code in there:

<?php 
/*
Plugin Name: Rotating Testimonials
Version: 0.1
Plugin URI: http://www.wpbeginner.com/
Description: Rotating Testimonials is a plugin that lets you add rotating testimonials in WordPress
Author: WPBeginner
Author URI: http://www.wpbeginner.com/
*/

add_action( 'init', 'wpb_register_cpt_testimonial' );

function wpb_register_cpt_testimonial() {

    $labels = array( 
        'name' => _x( 'Testimonials', 'testimonial' ),
        'singular_name' => _x( 'testimonial', 'testimonial' ),
        'add_new' => _x( 'Add New', 'testimonial' ),
        'add_new_item' => _x( 'Add New testimonial', 'testimonial' ),
        'edit_item' => _x( 'Edit testimonial', 'testimonial' ),
        'new_item' => _x( 'New testimonial', 'testimonial' ),
        'view_item' => _x( 'View testimonial', 'testimonial' ),
        'search_items' => _x( 'Search Testimonials', 'testimonial' ),
        'not_found' => _x( 'No testimonials found', 'testimonial' ),
        'not_found_in_trash' => _x( 'No testimonials found in Trash', 'testimonial' ),
        'parent_item_colon' => _x( 'Parent testimonial:', 'testimonial' ),
        'menu_name' => _x( 'Testimonials', 'testimonial' ),
    );

    $args = array( 
        'labels' => $labels,
        'hierarchical' => false,
        
        'supports' => array( 'title', 'editor', 'excerpt', 'author', 'thumbnail', 'custom-fields', 'revisions' ),
        
        'public' => true,
        'show_ui' => true,
        'show_in_menu' => true,
        
        
        'show_in_nav_menus' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => false,
        'has_archive' => true,
        'query_var' => true,
        'can_export' => true,
        'rewrite' => true,
        'capability_type' => 'post'
    );

    register_post_type( 'testimonial', $args );
}

$key = "testimonial";
$meta_boxes = array(
"person-name" => array(
"name" => "person-name",
"title" => "Person's Name",
"description" => "Enter the name of the person who gave you the testimonial."),
"position" => array(
"name" => "position",
"title" => "Position in Company",
"description" => "Enter their position in their specific company."),
"company" => array(
"name" => "company",
"title" => "Company Name",
"description" => "Enter the client Company Name"),
"link" => array(
"name" => "link",
"title" => "Client Link",
"description" => "Enter the link to client's site, or you can enter the link to your portfolio page where you have the client displayed.")
);
 
function wpb_create_meta_box() {
global $key;
 
if( function_exists( 'add_meta_box' ) ) {
add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Information', 'display_meta_box', 'testimonial', 'normal', 'high' );
}
}
 
function display_meta_box() {
global $post, $meta_boxes, $key;
?>
 
<div class="form-wrap">
 
<?php
wp_nonce_field( plugin_basename( __FILE__ ), $key . '_wpnonce', false, true );
 
foreach($meta_boxes as $meta_box) {
$data = get_post_meta($post->ID, $key, true);
?>
 
<div class="form-field form-required">
<label for="<?php echo $meta_box[ 'name' ]; ?>"><?php echo $meta_box[ 'title' ]; ?></label>
<input type="text" name="<?php echo $meta_box[ 'name' ]; ?>" value="<?php echo htmlspecialchars( $data[ $meta_box[ 'name' ] ] ); ?>" />
<p><?php echo $meta_box[ 'description' ]; ?></p>
</div>
 
<?php } ?>
 
</div>
<?php
}
 
function wpb_save_meta_box( $post_id ) {
global $post, $meta_boxes, $key;
 
foreach( $meta_boxes as $meta_box ) {
$data[ $meta_box[ 'name' ] ] = $_POST[ $meta_box[ 'name' ] ];
}
 
if ( !wp_verify_nonce( $_POST[ $key . '_wpnonce' ], plugin_basename(__FILE__) ) )
return $post_id;
 
if ( !current_user_can( 'edit_post', $post_id ))
return $post_id;
 
update_post_meta( $post_id, $key, $data );
}
 
add_action( 'admin_menu', 'wpb_create_meta_box' );
add_action( 'save_post', 'wpb_save_meta_box' );



function wpb_display_testimonials() { ?>
<script language="javascript"> 
$(document).ready(function(){
	$('#testimonials .slide');
	setInterval(function(){
		$('#testimonials .slide').filter(':visible').fadeOut(1000,function(){
			if($(this).next('.slide').size()){
				$(this).next().fadeIn(1000);
			}
			else{
				$('#testimonials .slide').eq(0).fadeIn(1000);
			}
		});
	},15000);	
});	
</script> 
<style type="text/css">
#testimonials .slide{color: #9c968e;}
#testimonials .client-contact-info{margin: 25px 0 0 0; float: left;}
#testimonials .testimonial-quote{background: url(images/quotebg.png) repeat-y; padding: 3px 0 0 65px; line-height: 1.5em; font-family: "proxima-nova-1", "proxima-nova-2", Helvetica, Arial, sans-serif !important; font-size: 16px; font-weight: normal; font-style: italic; margin: 10px 0 20px 0;}
</style>
<div id="testimonials">
<?php
$args = array( 'post_type' => 'testimonial', 'posts_per_page' => 100, 'orderby'   => 'menu_order', 'order'     => 'ASC' );
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();
$data = get_post_meta( $loop->post->ID, 'testimonial', true );
static $count = 0;
if ($count == "1") { ?>



<div class="slide" style="display: none;">
<div class="client-contact-info"><?php echo $data[ 'person-name' ]; ?>,&nbsp;<?php echo $data[ 'position' ]; ?>,&nbsp;<a href="<?php echo $data[ 'link' ]; ?>" title="<?php echo $data[ 'company' ]; ?>"><?php echo $data[ 'company' ]; ?></a></div>
<div class="clear"></div>
<div class="testimonial-quote"><?php the_content(); ?></div>
</div>
<?php }
else { ?>


<div class="slide">
<div class="client-contact-info"><?php echo $data[ 'person-name' ]; ?>,&nbsp;<?php echo $data[ 'position' ]; ?>,&nbsp;<a href="<?php echo $data[ 'link' ]; ?>" title="<?php echo $data[ 'company' ]; ?>"><?php echo $data[ 'company' ]; ?></a></div>
<div class="clear"></div>
<div class="testimonial-quote"><?php the_content(); ?></div>
</div>

<?php 
$count++; } 
endwhile; 
endif;
echo '</div>';
}
?>

Now open any theme file of yours where you want to display this, and simply paste the following code:

<?php wpb_display_testimonials(); ?>

You can simply override the style files if you look above. Note: if jQuery is not being added in your theme already, then you will have to add it.

We hope this works for you. Let us know if you find this article helpful.


Editorial Staff at WPBeginner is a team of WordPress lovers led by Syed Balkhi. Page maintained by Syed Balkhi.

WPBeginner's Video Icon
Our HD-Quality tutorial videos for WordPress Beginners will teach you how to use WordPress to create and manage your own website in about an hour. Get started now »

Comments

  1. Justin says:

    When I implement the plugint to my homepage (static), the page content ( the_content(); ) doesn’t show up, but the plugin works perfectly. I tried to change “function create_meta_box()” to “function make_meta_box();” but nothing happens…

  2. DM says:

    I’m rather new to this, so bear with me….I’m getting the following warning in all of the Testimonial Information fields:

    Warning: Illegal string offset ‘person-name’ in…. on line 107

    Which is the following line in the code in the wpb_create_meta_box function (~line 44 above):

    <input type="text" name="” value=”" />

    As far as I know I did a direct copy and paste. Any Ideas?

    Thanks!

  3. Joseph says:

    Any way to limit the height of the testimonials and auto add a … to the end? I run into the problem of different heights when I limit the wording because different words have different lengths. Maybe I should limit characters…. but I am interested in if one can limit height.

  4. uttam bhaskar says:

    Thanks for the post. It really works fine for me. Can you please let us know how can we add star rating and image file upload feature with this code.

  5. Doug says:

    Oh my word, you guys are rock stars!!! Thank you so much for sharing. I setup in about 15 min and it is working like a breeze.

    Anyway to add small controls for browsing through them?

  6. Ro says:

    Thanks for the tutorial. Everything works fine except that the slide is not going to the next slide. It keeps on going to the same slide over and over. I added three testimonials.

    • Editorial Staff says:

      The only reason it will do that if there is only one testimonial showing. Can you look in your source code to see that all 3 testimonials are there?

      • Ro says:

        Thanks for responding. Yes, but all of the same testimonial.

      • Tsnandra says:

        Hi, great plugin. Im getting the same problem. Everything works, but the testimonials dont rotate. Ive looked at the source code and I have the 3 testimonials that I added, with the correct content. It seems to be stuck on the first one, the others remain hidden. I’ve checked and I do have jquery included in the theme.

        • Editorial Staff says:

          The thing with jQuery is that there can be plugin conflict. If you have another jQuery plugin there, then there is a possibility that is what’s causing the testimonials to break.

        • Tsnandra says:

          For anyone else having the same problem as me. I managed to fix it, so simple but it worked!

          in the JQuery code replace $ with jQuery.

          Great plugin – thanks so much :)

        • Editorial Staff says:

          Thanks for sharing that fix. Hopefully that helps others if they encounter this problem.

  7. Tony says:

    Thank you so much for this great tool and for providing the code which allows us tech-newbies to use and learn from. I get most of it, but have one newbie question…

    Where do we add the Javascript code provided above? I am using WP 3.4.1 with the Thesis theme.

    Thanks,
    Tony

    • Editorial Staff says:

      You would have to add it in the thesis footer hook. Alternatively just add it in the wp_footer hook.

  8. George Serradinho says:

    Thanks for this tutorial, makes life so much easier now for me as a client was looking for something like this. I will probably make a few tweaks here and there, but at least the basics are there for me to start off with.

    Would be nice if you added a check to see if jquery was active or not, would help users who’s theme does not include it.

  9. Matt says:

    Thanks for this detailed tutorial. I’ve tried to get it working on my site but when I post the loop to display the testimonials on the page it doesn’t work – it simply shows the below code on the page. Any idea what might be causing this?

    $args = array( ‘post_type’ => ‘testimonial’, ‘posts_per_page’ => 10 );$loop = new WP_Query( $args );if ( $loop->have_posts() ) : while ( $loop->have_posts() ) : $loop->the_post();$data = get_post_meta( $loop->post->ID, ‘testimonial’, true );static $count = 0;if ($count == “1″) { ?>

    else { ?>

    , ,

    $count++; } endwhile; endif; ?>

  10. 256studio says:

    I get this error when activating the plugin.

    Cannot redeclare create_meta_box() (previously declared in /home/xxx_site_name/wp-content/themes/Core/fields/post.fields.php:85) in /home/xxx_site_name/wp-content/plugins/testimonials.php on line 79

    • wpbeginner says:

      @256studio That just means that another one of your plugins is using the same name create_meta_box. We took that snippet from WeFunction’s popular tutorial, so that could be the reason why. Change the name of the function” create_meta_box to something you like.

  11. sktanmoy says:

    Custom Post Type UI (WordPress Plugin) can help non coder :)

  12. easyP says:

    Wow!

    That looks really complicated for a non coder like me.

    They do say that code is poetry, but I’m not so sure. LOL

    Appreciate the work you guys put in and believe me… I can appreciate how much you know your stuff.

  13. wpbeginner says:

    The issue is being caused by the jQuery version and placement. Try adding jQuery 1.2.6 right above the testimonials function, and it should fix the issue.

  14. ElmervanEmpelen says:

    works like a charm, thx!

  15. Steph says:

    How do you add jQuery into the testimonials.php file? Thanks

Add a Comment

We're glad you have chosen to leave a comment. Please keep in mind that all comments are moderated according to our comment policy, and all links are nofollow. Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.