Separating WordPress comments from pings and trackbacks

Theme modification

So far we’ve written a function to separate our comments into $comments and $pings and now we need to display them. There should be no changes required to display comments as the pings have already been removed leaving us with a clean flow of conversation. We can decide to drop the display of pings entirely, or we can show them separately after the comments.

If we want to display them then we can duplicate the existing comment display code and re-use it to display pings. To do this copy the display code (as shown on page 2) and paste it immediately after itself. Edit the newly modified code to look like this (don’t worry, a full explanation is given below!):

<?php if ($comments) : ?>
	<h3 id="comments">
		<?php comments_number('No Responses','One Response','% Responses');?>
		to &#8220;<?php the_title(); ?>&#8221;
	</h3>

	<ol class="commentlist">

	<?php foreach ($comments as $comment) : ?>

		<li <?php echo $oddcomment; ?>id="comment-<?php comment_ID() ?>">
			<cite><?php comment_author_link() ?></cite> Says:
			<?php if ($comment->comment_approved == '0') : ?>
			<em>Your comment is awaiting moderation.</em>
			<?php endif; ?>
			<br />

			<small class="commentmetadata">
				<a href="#comment-<?php comment_ID() ?>" title="">
					<?php comment_date('F jS, Y') ?> at <?php comment_time() ?></a>
					<?php edit_comment_link('edit','&nbsp;&nbsp;',''); ?>
				</small>

			<?php comment_text() ?>

		</li>

	<?php
		/* Changes every other comment to a different class */
		$oddcomment = ( empty( $oddcomment ) ) ? 'class="alt" ' : '';
	?>

	<?php endforeach; /* end for each comment */ ?>

	</ol>

 <?php else : // this is displayed if there are no comments so far ?>

	<?php if ('open' == $post->comment_status) : ?>
		<!-- If comments are open, but there are no comments. -->

	 <?php else : // comments are closed ?>
		<!-- If comments are closed. -->
		<p class="nocomments">Comments are closed.</p>

	<?php endif; ?>
<?php endif; ?>

<?php global $pings; if ($pings) : ?>
	<h3 id="pings"><?php printf ('%d pings', count ($pings));?></h3>

	<ol class="commentlist">

	<?php foreach ($pings as $comment) : ?>

		<li <?php echo $oddcomment; ?>id="comment-<?php comment_ID() ?>">
			<cite><?php comment_author_link() ?></cite> Says:
			<?php if ($comment->comment_approved == '0') : ?>
			<em>Your comment is awaiting moderation.</em>
			<?php endif; ?>
			<br />

			<small class="commentmetadata">
				<a href="#comment-<?php comment_ID() ?>" title="">
					<?php comment_date('F jS, Y') ?> at <?php comment_time() ?></a>
				  <?php edit_comment_link('edit','&nbsp;&nbsp;',''); ?>
			</small>

			<?php comment_text() ?>

		</li>

	<?php
		/* Changes every other comment to a different class */
		$oddcomment = ( empty( $oddcomment ) ) ? 'class="alt" ' : '';
	?>

	<?php endforeach; /* end for each comment */ ?>

	</ol>
	<?php endif; ?>
<?php endif; ?>

To clarify, we’ve copied the code from lines 1 to 47 and pasted it into lines 49 to 82. We’ve then changed the heading (line 50), and changed the source of the list to use our recently added $pings variable (line 54). Note that we have to declare $pings as a global variable on line 49 otherwise we won’t have access to it.

A more compact method of display is to reduce the pings to a comma-separated list. Insert this immediately after the comments:

<?php

$display = array ();
foreach ($pings AS $comment)
  $display[] = sprintf ('<a href="%s" rel="nofollow">%s</a>', $comment->comment_author_url, $comment->comment_content);

echo implode (', ', $display);
?>

This will display the pings as follows:

Pings Reduced

14 comments

  1. Hi,
    I love the concept of this plugin because it cleans things up really nicely. However, is there an easy way to aggregate the pings in one place so you can keep the conversation easy and flowing, yet as a blogger be able to see easily (without visiting every post) who has pinged your site?

    Thanks!

  2. You would need a plugin to provide that functionality. It wouldn’t be difficult to implement, and just requires querying the database to fetch all pings.

  3. JHS, it is because you put the code to display the pings after the comment form. In comments.php just moved the pings code above the part that starts ‘leave a comment’.

  4. Hey there, this is a great page. How do you change the code so it says "1 ping" rather than "1 pings" if that’s the case? Also, ever since following your directions, the no self-ping plugin doesn’t work.

  5. Jessica, you can use something like:

    <?php echo sprintf (__ngettext ('%d post', '%d posts', $pings), $pings); ?>

    This will output '1 ping' or '2 pings'

  6. i’ve activated the separate-comments-pings plugin and have replaced my comments.php file with comments.php file (taken from default folder/zip, i download from this site). but i got error:

    Parse error: syntax error, unexpected T_ENDIF in /home/aufkgorg/public_html/wp-content/themes/vista/comments.php on line 144

    so, please give solution !

  7. Kevin, I had simmilar problem, find last and delete one

    John, I changed line from your previous comment, but it gives “1 posts”. Can you, please, check it?

  8. Hello there,

    First off thanks for a great plugin!

    Still I have a question. How did you get your pings and trackbacks so nice? I have used the piece of code you provided:


    foreach ($pings AS $comment)
    $display[] = sprintf ('%s',$comment->comment_author_url,$comment->comment_content); echo implode (', ', $display);?>

    But im still getting something that looks like this: […] Lets make our move… […]
    […] Lets make our move… […]

    How did you get yours so nicely like above: techathand.net, techie-buzz.com
    Just the main website name and it links to the specific article.

    Thanks in advance 🙂

  9. Now I’d love to know the code on how to separate pings from comments using WordPress version 2.7… 🙂 (i.e., when the threaded and paged comments functions are activated)

Comments are closed.