WordPress Tip: How To Separate Comments From Trackbacks & Pingbacks Using wp_list_comments Function

In this tutorial, I will show you how to separate pings (Trackbacks & Pingbacks) from comments when using the wp_list_comments() function in WordPress. The wp_list_comments() function is located in the comments.php file in your theme´s folder.

The wp_list_comments() purpose is to display all comments (including Trackbacks & Pingbacks) for posts based on a variety of parameters including ones set in the dashboard in Settings -> Discussion panel.

One functionality which is NOT part of WordPress core is the ability to separate between post comments and Pings. The two are entirely different and can be very confusing seeing them mixed together. It is much better to display Pings separately from Comments.

There are many tutorials showing how to separate comments from Pings using old methods for old versions of WordPress, but I did NOT find any tutorials on how to do it when a WordPress theme is using the wp_list_comments() function. This is where this tutorial is unique to detail the solution on separating Pings from Comments.

This tutorial applies to any WordPress theme that uses the wp_list_comments() function for displaying comments for a post or Page.

Features of The MODIFIED Comments Template | CODE-TT-O & CODE-X

If you get many comments (including Trackbacks and Pingbacks) on your blog, then you might want to separate Pings from Comments. In this case The Comment section on your blog become better readable and presentable.

Here are few features of the code:

  1. Adds Two separate sections: One for Comments only and the other for Pings only.
  2. Adds Two separate Headers: One for Comments only and the other for Pings only.
  3. Adds Two separate Counters: One for Comments only and the other for Pings only.
  4. Adds Two separate Navigation: One for Comments and the other for Pings.
  5. If there are Comments but NO Pings: The Pings header and navigation will not display. It does not make sense to say: “0 Pings to …”
  6. If there are NO comments and NO Pings: Then headers will not show. For example it does not make sense to say: “0 Comments to …”
  7. Code is tested to work properly on WordPress Version 3.0 and higher.
  8. There is a minor issue in the code: Even though, the comment pagination count is accurate for comments and pings sections. Clicking on one navigation section also affects the other section. The 2 navigation loops are semi-independent, but not totally. But for me, this is something that I can tolerate.

Real Example | WordPress Twenty Ten Theme

To give you an example. One of the popular WordPress themes is Twenty Ten. So I will be using the Twenty Ten theme as a learning and testing ground.

Below is the original (unedited) code of the comments.php File of the Twenty Ten theme (Version 1.3).

CODE-TT-O :: Original comments.php File :: Twenty Ten Theme (Version 1.3)

Note: To scroll within the code, you can also click on the code window and use your keyboard´s arrow keys.

<?php
/**
 * The template for displaying Comments.
 *
 * The area of the page that contains both current comments
 * and the comment form.  The actual display of comments is
 * handled by a callback to twentyten_comment which is
 * located in the functions.php file.
 *
 * @package WordPress
 * @subpackage Twenty_Ten
 * @since Twenty Ten 1.0
 */
?>

    <div id="comments">
<?php if ( post_password_required() ) : ?>
				<p class="nopassword"><?php _e( 'This post is password protected. Enter the password to view any comments.', 'twentyten' ); ?></p>
			</div><!-- #comments -->
<?php
		/* Stop the rest of comments.php from being processed,
		 * but don't kill the script entirely -- we still have
		 * to fully load the template.
		 */
		return;
	endif;
?>

<?php
	// You can start editing here -- including this comment!
?>

<?php if ( have_comments() ) : ?>
        <h3 id="comments-title"><?php
        printf( _n( 'One Response to %2$s', '%1$s Responses to %2$s', get_comments_number(), 'twentyten' ),
        number_format_i18n( get_comments_number() ), '<em>' . get_the_title() . '</em>' );
        ?></h3>

<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
        <div class="navigation">
        <div class="nav-previous"><?php previous_comments_link( __( '<span class="meta-nav">&larr;</span> Older Comments', 'twentyten' ) ); ?></div>
        <div class="nav-next"><?php next_comments_link( __( 'Newer Comments <span class="meta-nav">&rarr;</span>', 'twentyten' ) ); ?></div>
        </div> <!-- .navigation -->
<?php endif; // check for comment navigation ?>

    <ol class="commentlist">
        <?php
            /* Loop through and list the comments. Tell wp_list_comments()
             * to use twentyten_comment() to format the comments.
             * If you want to overload this in a child theme then you can
             * define twentyten_comment() and that will be used instead.
             * See twentyten_comment() in twentyten/functions.php for more.
             */
            wp_list_comments( array( 'callback' => 'twentyten_comment' ) );
        ?>
    </ol>

<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
        <div class="navigation">
        <div class="nav-previous"><?php previous_comments_link( __( '<span class="meta-nav">&larr;</span> Older Comments', 'twentyten' ) ); ?></div>
        <div class="nav-next"><?php next_comments_link( __( 'Newer Comments <span class="meta-nav">&rarr;</span>', 'twentyten' ) ); ?></div>
        </div><!-- .navigation -->
<?php endif; // check for comment navigation ?>

<?php else : // or, if we don't have comments:

	/* If there are no comments and comments are closed,
	 * let's leave a little note, shall we?
	 */
	if ( ! comments_open() ) :
?>
	<p class="nocomments"><?php _e( 'Comments are closed.', 'twentyten' ); ?></p>
<?php endif; // end ! comments_open() ?>

<?php endif; // end have_comments() ?>

<?php comment_form(); ?>
</div><!-- #comments -->

CODE-TT-O Notes:

For the purpose of this tutorial, the most important statement is line 54 of the code.

The wp_list_comments() function works on WordPress 2.7 and above. But I hope you will always upgrade to the latest version.

WordPress Twenty Eleven theme (Vers 1.3) also uses the same wp_list_comments() function. More on that later.

For the purpose of this tutorial, the code Reference is: wp_list_comments()

Result of Twenty Ten Theme Using Default comments.php | CODE-TT-O

The image below, shows how the Comments section for this Blog looks like when I use the Twenty Ten theme without any modifications to the Comment Template (default comments.php file). Notice how Pings and Comments are mixed together.

Twenty Ten Theme for this Blog: When using Default Comments template.

How can I Separate Pings from Comments in Twenty Ten Theme?

To tidy up your comments by separating Comments from Pings, there are Two Steps Involved:

STEP 1: You need to replace the Original/Default comments.php file above with the modified code below. Save it and upload it to your server.

CODE-TT-M :: Modified comments.php File :: Twenty Ten Theme (Vers 1.3)

Note: To scroll within the code, you can also click on the code window and use your keyboard´s arrow keys.

<?php
/***MODIFIED COMMENTS TEMPLATE FILE FOR TWENTY TEN THEME (VERSION 1.3)***
* @Author: Boutros AbiChedid 
* @Date:   February 22, 2012
* @Websites: bacsoftwareconsulting.com/ ; blueoliveonline.com/
* @Description: This is a Modified Comments template file that separates 
* Comments from Pings (Trackbacks and Pingbacks).
* The original Twenty Ten 'commments.php' file does not separate comments 
* from Pings. 
* @Tested on: WordPress version 3.3.1 
**************************************************************************/

/**
 * Twenty Ten Theme. The template for displaying Comments.
 *
 * The area of the page that contains both current comments
 * and the comment form.  The actual display of comments is
 * handled by a callback to twentyten_comment which is
 * located in the functions.php file.
 *
 * @package WordPress
 * @subpackage Twenty_Ten
 * @since Twenty Ten 1.0
 */
?>
<div id="comments">
<?php if ( post_password_required() ) : ?>
	<p class="nopassword"><?php _e( 'This post is password protected. Enter the password to view any comments.', 'twentyten' ); ?></p>
	</div><!-- #comments -->
<?php
	/* Stop the rest of comments.php from being processed,
	* but don't kill the script entirely -- we still have
	* to fully load the template.
	*/
		return;
	endif;
?>

<?php
	// You can start editing here -- including this comment!
?>

<?php if ( have_comments() ) : ?>

    <!-- COMMENTS SECTION -->
    <h3 id="comments-title"><?php
	//comments_only_count() is a custom function that must be added to 'functions.php' file.
    printf( _n( 'One Comment to %2$s', '%1$s Comments to %2$s', comments_only_count($count), 'twentyten' ),
    number_format_i18n( comments_only_count($count) ), '<em>' . get_the_title() . '</em>' );
    ?></h3>
     <ol class="commentlist">
        <?php 
		/* Loop through and list the comments. Tell wp_list_comments()
		 * to use twentyten_comment() to format the comments.
		 * If you want to overload this in a child theme then you can
		 * define twentyten_comment() and that will be used instead.
		 * See twentyten_comment() in twentyten/functions.php for more.
		 */
		 //It is important that the wp_list_comments is placed before the comment navigation (if it exists). 
		 //Otherwise, the comment navigation/pagination will be wrong.
		wp_list_comments('type=comment&callback=twentyten_comment');
        ?>
    </ol>

<?php if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there comments to navigate through? ?>
    <div class="navigation">
    <div class="nav-previous"><?php previous_comments_link( __( '<span class="meta-nav">&larr;</span> Older Comments', 'twentyten' ) ); ?></div>
    <div class="nav-next"><?php next_comments_link( __( 'Newer Comments <span class="meta-nav">&rarr;</span>', 'twentyten' ) ); ?></div>
    </div> <!-- .navigation -->
<?php endif; // check for comment navigation ?>
        
<!-- PINGS (TRACKBACKS & PINGBACKS) SECTION -->
<?php 
//If there are No pings, don't display the header and the navigation. One reason is that get_comment_pages_count() function is used to calculate the
//total number of comments pages. It does not separate for pings. So when the count is 0, the navigation still shows and it mimics the comments 
//section. Second reson if there are no Pings, then why display the header. 
	if ((get_comments_number() - comments_only_count($count)) > 0) { 

	echo '<h3 id="comments-title">';
	printf( _n( 'One Ping to %2$s', '%1$s Pings to %2$s', get_comments_number() - comments_only_count($count), 'twentyten' ),
	number_format_i18n( get_comments_number() - comments_only_count($count) ), '<em>' . get_the_title() . '</em>' );
	echo '</h3>'?>

	<ol class="commentlist">
		<?php
		wp_list_comments('type=pings&callback=twentyten_comment');
		?>
	</ol>
	<?php 
		//get_pings_pages_count() is a custom function that must be added to 'functions.php' file.
		if ( get_comment_pages_count() > 1 && get_option( 'page_comments' ) ) : // Are there Comments to navigate through? ?>
		 
		<div class="navigation">
		<div class="nav-previous"><?php previous_comments_link( __( '<span class="meta-nav">&larr;</span> Older Pings', 'twentyten' ) ); ?></div>
		<div class="nav-next"><?php next_comments_link( __( 'Newer Pings <span class="meta-nav">&rarr;</span>', 'twentyten' ) ); ?></div>
		</div><!-- .navigation -->  
						
		<?php endif; // check for comment navigation ?>
<?php } ?>

<?php else : // or, if we don't have comments:

	/* If there are no comments and comments are closed,
	 * let's leave a little note, shall we?
	 */
	if ( ! comments_open() ) :
?>
	<p class="nocomments"><?php _e( 'Comments are closed.', 'twentyten' ); ?></p>
<?php endif; // end ! comments_open() ?>

<?php endif; // end have_comments() ?>

<?php comment_form(); ?>
</div><!-- #comments -->

STEP 2: Open functions.php file located in your theme´s folder, and add (copy and paste) the following CODE-X. Save it and upload it to the server.

CODE-X is needed so that Pings are counted separately from Comments. WordPress has only the get_comments_number() template tag that retrieves the value of the total count of comments, Trackbacks, and Pingbacks for a post.

CODE-X :: functions.php File

<?php
/***********CODE USED BY THE MODIFIED COMMENTS TEMPLATE FILE***********
* @Author: Boutros AbiChedid 
* @Date:   February 22, 2012
* @Websites: bacsoftwareconsulting.com/ ; blueoliveonline.com/
* @Description: FUNCTION-1: returns only the number of comments.
* I wrote my own function, because the default "get_comments_number()" 
* counts all comments including pings.
* Pings_only_count = get_comments_number() - comments_only_count($count)
* @Tested on: WordPress version 3.3.1 
************************************************************************/
//FUNCTION-1.
function comments_only_count( $count ) {  
	//Filter the comments count in the front-end.
	if ( ! is_admin() ) {
		global $id;
		$comments_by_type = &separate_comments( get_comments( 'status=approve&post_id=' . $id ) );
		return count( $comments_by_type['comment'] );
	} 
	//When in the WP-admin back end, do NOT filter comments (and pings) count.
	else {
		return $count;
	}
}
?>

To separate Comments from Pings you must use both CODE-TT-M as your new comments.php file AND you must add CODE-X to your theme´s functions.php file.

Keep a backup copy of orginal comments.php file, in case you want to revert back.

Result of Twenty Ten Theme Using MODIFIED comments.php | (CODE-TT-M AND CODE-X)

The image below shows how the modified Comment section looks after implementing CODE-TT-M AND CODE-X. Notice How the Comments are Now separated from Pings.

Twenty Ten theme: Modified comments Section. Separating Comments from Pings and Using Default Navigation.

I want to Paginate Comments. What Should I do?

The default wordPress Twenty Ten theme uses only the « Older Comments and/or Newer Comments » links to break comments into pages.

If you like to paginate comments into numbered pages, then locate Lines 67-68 and lines 94-95 of CODE-TT-M and replace them with the following Line of code:

Line-P :: Paginate Comments and Pings

<?php 
paginate_comments_links() 
?>

Line-P Notes:

You still need CSS to style the Comments/Pings numbered links.

You will need to set up the options in the WordPress dashboard (Settings -> Discussion) for paging to work.

Reference: paginate_comments_links()

Check a Previous tutorial that helps you with this: How To Add WordPress Comment Pagination Without a Plugin.

Result of MODIFIED Twenty Ten Theme When Using Line-P

The 2 images below, shows The modified Twenty Ten theme when replacing Lines 67-68 and Lines 94-95 of CODE-TT-M with Line-P:

Twenty Ten Theme: Modified Comments Section. Separate Comments from Pings. Also using Numbered Pagination for Comments.

Twenty Ten Theme: Modified Comments Section. Separate Comments from Pings. Also using Numbered Pagination for Comments. Case of No Pings.

Where To Enable Paged Comments in WordPress?

To enable Paged Comments, or the default comment navigation for your WordPress blog, Login to your WordPress dashboard. On the Left Panel of your Administration Screens, go to Settings -> Discussion as shown in the image below.

Setting the Comments Pagination in WordPress dashboard.

I am Using WordPress Twenty Eleven Theme. Can you Help me With That?

The template for displaying Comments for WordPress Twenty Eleven Theme (Version 1.3) is similar to Twenty Ten, you can follow the same procedure in this tutorial with probably some minor tweaking, and you should be all set.

If you want me to help you with separating Comments from Pings, then a donation would be greatly appreciated.

Your Turn to Talk

Now you know what to do if you want to Separate Comments From Trackbacks/Pingbacks from the wp_list_comments() output. This tutorial applies to any WordPress theme that uses the wp_list_comments() function to display comments.

If you have something to add or anything else to say, please share your opinion or questions in the comments section. Your opinion matters, unless it is a Spam.

If you found this post useful, please consider: linking back to it, subscribing by email to future posts, or subscribing to the RSS feed to have new articles delivered to your feed reader, or feel free to donate. Thanks!

About the Author |
Boutros is a professional Drupal & WordPress developer, Web developer, Web designer, Software Engineer and Blogger. He strives for pixel perfect design, clean robust code, and user-friendly interface. If you have a project in mind and like his work, feel free to contact him. Connect with Boutros on Twitter, and LinkedIn.
Visit Boutros AbiChedid Website.

6 Responses to “WordPress Tip: How To Separate Comments From Trackbacks & Pingbacks Using wp_list_comments Function”

  1. Sean Davis says:

    Thanks a ton, bud. I needed this.

    I’m running into a little issue, though. Your code is perfectly fine but I’m having trouble figuring out how to make some adjustments to do what I need done.

    Right now, I’m using comments_number() on my blog feed to show the total number of “responses” in the byline. Then, on the single posts, I am using your wonderful code to separate my comments from my pings beneath the article content.

    Well, I want to keep the number of “responses” in the byline on the single posts. However, the theme I have built has an option to hide the pings beneath the article. So, if they choose to do so, only the comments will show… which is fine. But now it “looks” like there’s an error because the comment count beneath the article will not match the the number of “responses” in the byline (which, remember, uses comment_number()).

    Do you know of a way to use your code in the byline? When the user chooses to hide pings, I’m trying to write a conditional that will subtract the number of pings (just like in your code) from the number of “responses” in the byline. That way everything always matches.

    As of now, I simply show “responses” on the blog feed in the byline and I hide it on the single posts. Any help would be appreciated.

    Sean

  2. Ronald Scott says:

    Hello I’m Ronald. Your article is great.

  3. Faisal says:

    Thank you very much. I’ve been looking for ways to separate the list of comments and pingback for a long time. Finally I get the trick here.

  4. For a long time I was struggling with pingbacks and comment.
    Thanks a lots!!!