wp_list_comments( string|array $args = array(), WP_Comment[] $comments = null ): void|string

Displays a list of comments.

Description

Used in the comments.php template to list comments for a particular post.

See also

  • WP_Query::$comments

Parameters

$argsstring|arrayoptional
Formatting options.
  • walker object
    Instance of a Walker class to list comments. Default null.
  • max_depth int
    The maximum comments depth.
  • style string
    The style of list ordering. Accepts 'ul', 'ol', or 'div'.
    'div' will result in no additional list markup. Default 'ul'.
  • callback callable
    Callback function to use. Default null.
  • end-callback callable
    Callback function to use at the end. Default null.
  • type string
    Type of comments to list. Accepts 'all', 'comment', 'pingback', 'trackback', 'pings'. Default 'all'.
  • page int
    Page ID to list comments for.
  • per_page int
    Number of comments to list per page.
  • avatar_size int
    Height and width dimensions of the avatar size. Default 32.
  • reverse_top_level bool
    Ordering of the listed comments. If true, will display newest comments first. Default null.
  • reverse_children bool
    Whether to reverse child comments in the list. Default null.
  • format string
    How to format the comments list. Accepts 'html5', 'xhtml'.
    Default 'html5' if the theme supports it.
  • short_ping bool
    Whether to output short pings. Default false.
  • echo bool
    Whether to echo the output or return it. Default true.

Default:array()

$commentsWP_Comment[]optional
Array of WP_Comment objects.

Default:null

Return

void|string Void if 'echo' argument is true, or no comments to list.
Otherwise, HTML list of comments.

More Information

Default options for $args

$args = array( 'walker' => null, 'max_depth' => '', 'style' => 'ul', 'callback' => null, 'end-callback' => null, 'type' => 'all', 'page' => '', 'per_page' => '', 'avatar_size' => 32, 'reverse_top_level' => null, 'reverse_children' => '', 'format' => 'html5', // or 'xhtml' if no 'HTML5' theme support 'short_ping' => false, // @since 3.6 'echo' => true // boolean, default is true );

The ‘max_depth‘, ‘per_page‘, and ‘reverse_top_level‘ parameters can be more easily controlled through the Discussion Settings Administration Panel but a theme can override those settings.

Source

function wp_list_comments( $args = array(), $comments = null ) {	global $wp_query, $comment_alt, $comment_depth, $comment_thread_alt, $overridden_cpage, $in_comment_loop;	$in_comment_loop = true;	$comment_alt = 0;	$comment_thread_alt = 0;	$comment_depth = 1;	$defaults = array(	'walker' => null,	'max_depth' => '',	'style' => 'ul',	'callback' => null,	'end-callback' => null,	'type' => 'all',	'page' => '',	'per_page' => '',	'avatar_size' => 32,	'reverse_top_level' => null,	'reverse_children' => '',	'format' => current_theme_supports( 'html5', 'comment-list' ) ? 'html5' : 'xhtml',	'short_ping' => false,	'echo' => true,	);	$parsed_args = wp_parse_args( $args, $defaults );	/** * Filters the arguments used in retrieving the comment list. * * @since 4.0.0 * * @see wp_list_comments() * * @param array $parsed_args An array of arguments for displaying comments. */	$parsed_args = apply_filters( 'wp_list_comments_args', $parsed_args );	// Figure out what comments we'll be looping through ($_comments).	if ( null !== $comments ) {	$comments = (array) $comments;	if ( empty( $comments ) ) {	return;	}	if ( 'all' !== $parsed_args['type'] ) {	$comments_by_type = separate_comments( $comments );	if ( empty( $comments_by_type[ $parsed_args['type'] ] ) ) {	return;	}	$_comments = $comments_by_type[ $parsed_args['type'] ];	} else {	$_comments = $comments;	}	} else {	/* * If 'page' or 'per_page' has been passed, and does not match what's in $wp_query, * perform a separate comment query and allow Walker_Comment to paginate. */	if ( $parsed_args['page'] || $parsed_args['per_page'] ) {	$current_cpage = (int) get_query_var( 'cpage' );	if ( ! $current_cpage ) {	$current_cpage = 'newest' === get_option( 'default_comments_page' ) ? 1 : $wp_query->max_num_comment_pages;	}	$current_per_page = (int) get_query_var( 'comments_per_page' );	if ( (int) $parsed_args['page'] !== $current_cpage || (int) $parsed_args['per_page'] !== $current_per_page ) {	$comment_args = array(	'post_id' => get_the_ID(),	'orderby' => 'comment_date_gmt',	'order' => 'ASC',	'status' => 'approve',	);	if ( is_user_logged_in() ) {	$comment_args['include_unapproved'] = array( get_current_user_id() );	} else {	$unapproved_email = wp_get_unapproved_comment_author_email();	if ( $unapproved_email ) {	$comment_args['include_unapproved'] = array( $unapproved_email );	}	}	$comments = get_comments( $comment_args );	if ( 'all' !== $parsed_args['type'] ) {	$comments_by_type = separate_comments( $comments );	if ( empty( $comments_by_type[ $parsed_args['type'] ] ) ) {	return;	}	$_comments = $comments_by_type[ $parsed_args['type'] ];	} else {	$_comments = $comments;	}	}	// Otherwise, fall back on the comments from `$wp_query->comments`.	} else {	if ( empty( $wp_query->comments ) ) {	return;	}	if ( 'all' !== $parsed_args['type'] ) {	if ( empty( $wp_query->comments_by_type ) ) {	$wp_query->comments_by_type = separate_comments( $wp_query->comments );	}	if ( empty( $wp_query->comments_by_type[ $parsed_args['type'] ] ) ) {	return;	}	$_comments = $wp_query->comments_by_type[ $parsed_args['type'] ];	} else {	$_comments = $wp_query->comments;	}	if ( $wp_query->max_num_comment_pages ) {	$default_comments_page = get_option( 'default_comments_page' );	$cpage = (int) get_query_var( 'cpage' );	if ( 'newest' === $default_comments_page ) {	$parsed_args['cpage'] = $cpage;	} elseif ( 1 === $cpage ) {	/* * When the first page shows the oldest comments, * post permalink is the same as the comment permalink. */	$parsed_args['cpage'] = '';	} else {	$parsed_args['cpage'] = $cpage;	}	$parsed_args['page'] = 0;	$parsed_args['per_page'] = 0;	}	}	}	if ( '' === $parsed_args['per_page'] && get_option( 'page_comments' ) ) {	$parsed_args['per_page'] = get_query_var( 'comments_per_page' );	}	if ( empty( $parsed_args['per_page'] ) ) {	$parsed_args['per_page'] = 0;	$parsed_args['page'] = 0;	}	if ( '' === $parsed_args['max_depth'] ) {	if ( get_option( 'thread_comments' ) ) {	$parsed_args['max_depth'] = get_option( 'thread_comments_depth' );	} else {	$parsed_args['max_depth'] = -1;	}	}	if ( '' === $parsed_args['page'] ) {	if ( empty( $overridden_cpage ) ) {	$parsed_args['page'] = get_query_var( 'cpage' );	} else {	$threaded = ( -1 !== (int) $parsed_args['max_depth'] );	$parsed_args['page'] = ( 'newest' === get_option( 'default_comments_page' ) ) ? get_comment_pages_count( $_comments, $parsed_args['per_page'], $threaded ) : 1;	set_query_var( 'cpage', $parsed_args['page'] );	}	}	// Validation check.	$parsed_args['page'] = (int) $parsed_args['page'];	$parsed_args['per_page'] = (int) $parsed_args['per_page'];	if ( 0 === $parsed_args['page'] && 0 !== $parsed_args['per_page'] ) {	$parsed_args['page'] = 1;	}	if ( null === $parsed_args['reverse_top_level'] ) {	$parsed_args['reverse_top_level'] = ( 'desc' === get_option( 'comment_order' ) );	}	if ( empty( $parsed_args['walker'] ) ) {	$walker = new Walker_Comment();	} else {	$walker = $parsed_args['walker'];	}	$output = $walker->paged_walk( $_comments, $parsed_args['max_depth'], $parsed_args['page'], $parsed_args['per_page'], $parsed_args );	$in_comment_loop = false;	if ( $parsed_args['echo'] ) {	echo $output;	} else {	return $output;	} } 

Hooks

apply_filters( ‘wp_list_comments_args’, array $parsed_args )

Filters the arguments used in retrieving the comment list.

Changelog

VersionDescription
2.7.0Introduced.

User Contributed Notes

  1. Skip to note 8 content

    Example migrated from Codex:

    Comments Only With A Custom Comment Display

    Displays just comments (no pingbacks or trackbacks) while using a custom callback function to control the look of the comment. You may want to add a max_depth=X parameter, if the reply links are not appearing.

    <ul class="commentlist"> <?php wp_list_comments( 'type=comment&callback=mytheme_comment' ); ?> </ul>

    You will need to define your custom callback function in your theme’s functions.php file. Here is an example:

    function mytheme_comment($comment, $args, $depth) { if ( 'div' === $args['style'] ) { $tag = 'div'; $add_below = 'comment'; } else { $tag = 'li'; $add_below = 'div-comment'; }?> <<?php echo $tag; ?> <?php comment_class( empty( $args['has_children'] ) ? '' : 'parent' ); ?> id="comment-<?php comment_ID() ?>"><?php if ( 'div' != $args['style'] ) { ?> <div id="div-comment-<?php comment_ID() ?>" class="comment-body"><?php } ?> <div class="comment-author vcard"><?php if ( $args['avatar_size'] != 0 ) { echo get_avatar( $comment, $args['avatar_size'] ); } printf( __( '<cite class="fn">%s</cite> <span class="says">says:</span>' ), get_comment_author_link() ); ?> </div><?php if ( $comment->comment_approved == '0' ) { ?> <em class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ); ?></em><br/><?php } ?> <div class="comment-meta commentmetadata"> <a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ); ?>"><?php /* translators: 1: date, 2: time */ printf( __('%1$s at %2$s'), get_comment_date(), get_comment_time() ); ?> </a><?php edit_comment_link( __( '(Edit)' ), ' ', '' ); ?> </div> <?php comment_text(); ?> <div class="reply"><?php comment_reply_link( array_merge( $args, array( 'add_below' => $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth'] ) ) ); ?> </div><?php if ( 'div' != $args['style'] ) : ?> </div><?php endif; }

    Note the lack of a trailing </li>. In order to accommodate nested replies, WordPress will add the appropriate closing tag after listing any child elements.

  2. Skip to note 9 content

    If you are using WordPress 4.9.6 or higher and not showing “Comment is awaiting moderation” alert.

    You can follow the steps below.

    – ) Settings -> Discussion -> enable “Show comments cookies opt-in checkbox.”
    – ) After activating checkbox will show on comments form like this. “Save my name, email, and website in this browser for the next time I comment.”

    That’s it.

    If you want to customize this checkbox field, you can use this code.

    $comment_form = array( 'fields' => array( 'cookies' => '<p class="comment-form-cookies-consent"><input id="wp-comment-cookies-consent" name="wp-comment-cookies-consent" type="checkbox" value="yes"' . $consent . ' />' . '<label for="wp-comment-cookies-consent">' . __( 'Save my name, email, and website in this browser for the next time I comment.' ) . '</label></p>', ), ); comment_form( $comment_form );
  3. Skip to note 10 content
    Anonymous User

    wp_list_comments() will not do anything by itself. It has to be called from inside the comments template file.

    An example:

    The page/post file where you want to insert comments:

    <?php comments_template('/comments.php'); ?> <?php /* Calling just comments_template() is also fine */ ?>

    Then, in comments.php:

    <div>	<?php /* Add conditional checks, styling and arguments here... */ ?>	<?php wp_list_comments(); ?> </div>
  4. Skip to note 11 content

    Example migrated from Codex:

    Outputs an ordered list of comments for a specific page or post. Things like threading or paging being enabled or disabled are controlled via the Settings Discussion SubPanel.

    <ol class="commentlist">	<?php	//Gather comments for a specific page/post	$comments = get_comments(array(	'post_id' => XXX,	'status' => 'approve' //Change this to the type of comments to be displayed	));	//Display the list of comments	wp_list_comments(array(	'per_page' => 10, //Allow comment pagination	'reverse_top_level' => false //Show the oldest comments at the top of the list	), $comments);	?> </ol>
  5. Skip to note 13 content

    Example migrated from Codex:

    Default Usage

    Outputs an ordered list of the comments. Things like threading or paging being enabled or disabled are controlled via the Settings Discussion SubPanel.

    <ol class="commentlist"> <?php wp_list_comments(); ?> </ol>
  6. Skip to note 14 content
    $cpage = get_query_var( 'cpage' ) ? get_query_var( 'cpage' ) : 1; wp_list_comments( array( 'avatar_size' => 60, 'short_ping' => true, 'type' => 'comment', 'callback' => 'ic_comment_list', 'per_page' => get_option( 'comments_per_page' ), 'page' => $cpage, 'reverse_top_level' => get_option( 'default_comments_page' ) === 'oldest' ? false : true, ) );

You must log in before being able to contribute a note or feedback.