Linked-in profile Github profile Twitter profile Curriculum vitae
Categories: WordPress
Created
11th January 2017
Modified
6th February 2020

Display the number of replies to a comment on WordPress

This tutorial can be applied to any of the Walker classes in WordPress to track the number of items (children) associated with an element (the parent).

First off, for the sake of people searching Google for a solution to finding out how many children are associated with a Walker element in WordPress. You’re in the right place! It’s just a case of semantics, the code below could be used to create a custom Walker_Nav_Menu to show the number of items in a menu branch.

We’ll go over how to show the number of replies to individual comments. All modifications from here on are based on the WordPress twentysixteen theme.

Check the comments section below to see this code in action for the number of replies to comments.

In this tutorial example we will need to modify the functions.php where we will place the custom Walker_Comment class to track the number of replies, and the comments.php template to use the custom walker class.

The AGW_Walker_Comment class

Here is the code for the custom Walker_Comment class which I have called AGW_Walker_Comment it contains an extension of the functions Walker::display_element() and Walker_Comment::comment() classes (WordPress version 4.7 at the time of writing).

The extended display_element() function notes the number of children, which can be used throughout the entire element scope, meaning you can extend the start_el(), start_lvl(), end_lvl() and end_el() functions and still have access to $this->total_children.

class AGW_Walker_Comment extends Walker_Comment {
  public $total_children;
  public function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
    if ( ! $element ) {
      return;
    }
    $id_field = $this->db_fields['id'];
    $id       = $element->$id_field;
    $this->total_children = 0;
    if ( ! empty( $children_elements[ $id ] ) ) {
      $this->total_children = count( $children_elements[ $id ] );
    }
    parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
  }
  protected function comment( $comment, $depth, $args ) {
    if ( 'div' == $args['style'] ) {
      $tag = 'div';
      $add_below = 'comment';
    } else {
      $tag = 'li';
      $add_below = 'div-comment';
    }
    ?>
    < <?php echo $tag; ?> <?php comment_class( $this->has_children ? 'parent' : '', $comment ); ?> id="comment-<?php comment_ID(); ?>">
    <?php if ( 'div' != $args['style'] ) : ?>
      <div id="div-comment-<?php comment_ID(); ?>" class="comment-body">
    <?php endif; ?>
    <div class="comment-author vcard">
      <?php if ( 0 != $args['avatar_size'] ) echo get_avatar( $comment, $args['avatar_size'] ); ?>
      <?php printf( __( '<cite class="fn">%s</cite> <span class="says">says:</span>' ), get_comment_author_link( $comment ) ); ?>
    </div>
    <?php if ( '0' == $comment->comment_approved ) : ?>
      <em class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ) ?></em>
      <br />
    <?php endif; ?>
    <div class="comment-meta commentmetadata"><a href="<?php echo esc_url( get_comment_link( $comment, $args ) ); ?>">
        <?php
        /* translators: 1: comment date, 2: comment time */
        printf( __( '%1$s at %2$s' ), get_comment_date( '', $comment ),  get_comment_time() ); ?></a><?php edit_comment_link( __( '(Edit)' ), '  ', '' );
      ?>
    </div>
    <?php comment_text( $comment, array_merge( $args, array( 'add_below' => $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?>
    <?php
    comment_reply_link( array_merge( $args, array(
      'add_below' => $add_below,
      'depth'     => $depth,
      'max_depth' => $args['max_depth'],
      'before'    => '<div class="reply">',
      'after'     => '</div>'
    ) ) );
    ?>
    <?php if ( $this->total_children > 0 ) : ?>
      <span><?php printf( _n( '%s reply', '%s replies', $this->total_children ), $this->total_children ) ?></span>
    <?php endif; ?>
    <?php if ( 'div' != $args['style'] ) : ?>
      </div>
    <?php endif; ?>
    <?php
  }
}

The display_element() function

The changes to the display_element() function track the number of children (replies), to the parent (the comment) with the variable $this->total_children , then executes the original parent::display_element()

$id_field = $this->db_fields['id'];
$id       = $element->$id_field;
$this->total_children = 0;
if ( ! empty( $children_elements[ $id ] ) ) {
  $this->total_children = count( $children_elements[ $id ] );
}
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );

The comment() function

Then we add the number of replies for the comment template in the comment() function. Feel free to put this code where ever you like on the template and reword the phrasing to suit your requirements.

<?php if ( $this->total_children > 0 ) : ?>
  <span><?php printf( _n( '%s reply', '%s replies', $this->total_children ), $this->total_children ) ?></span>
<?php endif; ?>

The comments.php template

Next we need to update the comments.php template to use the new AGW_Walker_Comment  class and show the number of replies for each comment. Look for the wp_list_comments() function in the code of the comments template, for example the code in the twentysixteen theme’s comments.php looks like this.

wp_list_comments( array(
  'style'       => 'ol',
  'short_ping'  => true,
  'avatar_size' => 42,
) );

We want to add another argument to the array called walker with an instance of the AGW_Walker_Comment class with the updated functions like so.

wp_list_comments( array(
  'walker'      => new AGW_Walker_Comment,
  'style'       => 'ol',
  'short_ping'  => true,
  'avatar_size' => 42,
) );

Thats it, give it a try and modify as you need. Comment below if you have suggestions or any issues.

Side note

I’ve submitted a slightly different variation of this to the WordPress Trac in hopes they might include this modification in the core Walker class, which would remove the need for the extended display_element() function in your themes functions.php when needing this data.

Leave a Reply