* Returns the classes for the comment div as an array.
* @since 4.4.0 Added the ability for `$comment_id` to also accept a WP_Comment object.
* @global int $comment_alt
* @global int $comment_depth
* @global int $comment_thread_alt
* @param string|string[] $css_class Optional. One or more classes to add to the class list.
* @param int|WP_Comment $comment_id Optional. Comment ID or WP_Comment object. Default current comment.
* @param int|WP_Post $post Optional. Post ID or WP_Post object. Default current post.
* @return string[] An array of classes.
function get_comment_class( $css_class = '', $comment_id = null, $post = null ) {
global $comment_alt, $comment_depth, $comment_thread_alt;
$comment = get_comment( $comment_id );
// Get the comment type (comment, trackback).
$classes[] = ( empty( $comment->comment_type ) ) ? 'comment' : $comment->comment_type;
// Add classes for comment authors that are registered users.
$user = $comment->user_id ? get_userdata( $comment->user_id ) : false;
$classes[] = 'comment-author-' . sanitize_html_class( $user->user_nicename, $comment->user_id );
// For comment authors who are the author of the post.
$_post = get_post( $post );
if ( $comment->user_id === $_post->post_author ) {
$classes[] = 'bypostauthor';
if ( empty( $comment_alt ) ) {
if ( empty( $comment_depth ) ) {
if ( empty( $comment_thread_alt ) ) {
if ( $comment_alt % 2 ) {
// Alt for top-level comments.
if ( 1 === $comment_depth ) {
if ( $comment_thread_alt % 2 ) {
$classes[] = 'thread-odd';
$classes[] = 'thread-alt';
$classes[] = 'thread-even';
$classes[] = "depth-$comment_depth";
if ( ! empty( $css_class ) ) {
if ( ! is_array( $css_class ) ) {
$css_class = preg_split( '#\s+#', $css_class );
$classes = array_merge( $classes, $css_class );
$classes = array_map( 'esc_attr', $classes );
* Filters the returned CSS classes for the current comment.
* @param string[] $classes An array of comment classes.
* @param string[] $css_class An array of additional classes added to the list.
* @param string $comment_id The comment ID as a numeric string.
* @param WP_Comment $comment The comment object.
* @param int|WP_Post $post The post ID or WP_Post object.
return apply_filters( 'comment_class', $classes, $css_class, $comment->comment_ID, $comment, $post );
* Retrieves the comment date of the current comment.
* @since 4.4.0 Added the ability for `$comment_id` to also accept a WP_Comment object.
* @param string $format Optional. PHP date format. Defaults to the 'date_format' option.
* @param int|WP_Comment $comment_id Optional. WP_Comment or ID of the comment for which to get the date.
* Default current comment.
* @return string The comment's date.
function get_comment_date( $format = '', $comment_id = 0 ) {
$comment = get_comment( $comment_id );
$_format = ! empty( $format ) ? $format : get_option( 'date_format' );
$comment_date = mysql2date( $_format, $comment->comment_date );
* Filters the returned comment date.
* @param string|int $comment_date Formatted date string or Unix timestamp.
* @param string $format PHP date format.
* @param WP_Comment $comment The comment object.
return apply_filters( 'get_comment_date', $comment_date, $format, $comment );
* Displays the comment date of the current comment.
* @since 4.4.0 Added the ability for `$comment_id` to also accept a WP_Comment object.
* @param string $format Optional. PHP date format. Defaults to the 'date_format' option.
* @param int|WP_Comment $comment_id WP_Comment or ID of the comment for which to print the date.
* Default current comment.
function comment_date( $format = '', $comment_id = 0 ) {
echo get_comment_date( $format, $comment_id );
* Retrieves the excerpt of the given comment.
* Returns a maximum of 20 words with an ellipsis appended if necessary.
* @since 4.4.0 Added the ability for `$comment_id` to also accept a WP_Comment object.
* @param int|WP_Comment $comment_id Optional. WP_Comment or ID of the comment for which to get the excerpt.
* Default current comment.
* @return string The possibly truncated comment excerpt.
function get_comment_excerpt( $comment_id = 0 ) {
$comment = get_comment( $comment_id );
if ( ! post_password_required( $comment->comment_post_ID ) ) {
$comment_text = strip_tags( str_replace( array( "\n", "\r" ), ' ', $comment->comment_content ) );
$comment_text = __( 'Password protected' );
/* translators: Maximum number of words used in a comment excerpt. */
$comment_excerpt_length = (int) _x( '20', 'comment_excerpt_length' );
* Filters the maximum number of words used in the comment excerpt.
* @param int $comment_excerpt_length The amount of words you want to display in the comment excerpt.
$comment_excerpt_length = apply_filters( 'comment_excerpt_length', $comment_excerpt_length );
$comment_excerpt = wp_trim_words( $comment_text, $comment_excerpt_length, '…' );
* Filters the retrieved comment excerpt.
* @since 4.1.0 The `$comment_id` and `$comment` parameters were added.
* @param string $comment_excerpt The comment excerpt text.
* @param string $comment_id The comment ID as a numeric string.
* @param WP_Comment $comment The comment object.
return apply_filters( 'get_comment_excerpt', $comment_excerpt, $comment->comment_ID, $comment );
* Displays the excerpt of the current comment.
* @since 4.4.0 Added the ability for `$comment_id` to also accept a WP_Comment object.
* @param int|WP_Comment $comment_id Optional. WP_Comment or ID of the comment for which to print the excerpt.
* Default current comment.
function comment_excerpt( $comment_id = 0 ) {
$comment = get_comment( $comment_id );
$comment_excerpt = get_comment_excerpt( $comment );
* Filters the comment excerpt for display.
* @since 4.1.0 The `$comment_id` parameter was added.
* @param string $comment_excerpt The comment excerpt text.
* @param string $comment_id The comment ID as a numeric string.
echo apply_filters( 'comment_excerpt', $comment_excerpt, $comment->comment_ID );
* Retrieves the comment ID of the current comment.
* @return string The comment ID as a numeric string.
function get_comment_ID() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
$comment = get_comment();
$comment_id = ! empty( $comment->comment_ID ) ? $comment->comment_ID : '0';
* Filters the returned comment ID.
* @since 4.1.0 The `$comment` parameter was added.
* @param string $comment_id The current comment ID as a numeric string.
* @param WP_Comment $comment The comment object.
return apply_filters( 'get_comment_ID', $comment_id, $comment ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.NotLowercase
* Displays the comment ID of the current comment.
function comment_ID() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
* Retrieves the link to a given comment.
* @since 4.4.0 Added the ability for `$comment` to also accept a WP_Comment object. Added `$cpage` argument.
* @see get_page_of_comment()
* @global WP_Rewrite $wp_rewrite WordPress rewrite component.
* @global bool $in_comment_loop
* @param WP_Comment|int|null $comment Optional. Comment to retrieve. Default current comment.
* An array of optional arguments to override the defaults.
* @type string $type Passed to get_page_of_comment().
* @type int $page Current page of comments, for calculating comment pagination.
* @type int $per_page Per-page value for comment pagination.
* @type int $max_depth Passed to get_page_of_comment().
* @type int|string $cpage Value to use for the comment's "comment-page" or "cpage" value.
* If provided, this value overrides any value calculated from `$page`
* @return string The permalink to the given comment.
function get_comment_link( $comment = null, $args = array() ) {
global $wp_rewrite, $in_comment_loop;
$comment = get_comment( $comment );
if ( ! is_array( $args ) ) {
$args = array( 'page' => $args );
$args = wp_parse_args( $args, $defaults );
$comment_link = get_permalink( $comment->comment_post_ID );
// The 'cpage' param takes precedence.
if ( ! is_null( $args['cpage'] ) ) {
// No 'cpage' is provided, so we calculate one.
if ( '' === $args['per_page'] && get_option( 'page_comments' ) ) {
$args['per_page'] = get_option( 'comments_per_page' );
if ( empty( $args['per_page'] ) ) {
if ( ! empty( $in_comment_loop ) ) {
$cpage = (int) get_query_var( 'cpage' );
// Requires a database hit, so we only do it when we can't figure out from context.
$cpage = get_page_of_comment( $comment->comment_ID, $args );
* If the default page displays the oldest comments, the permalinks for comments on the default page
* do not need a 'cpage' query var.
if ( 'oldest' === get_option( 'default_comments_page' ) && 1 === $cpage ) {
if ( $cpage && get_option( 'page_comments' ) ) {
if ( $wp_rewrite->using_permalinks() ) {
$comment_link = trailingslashit( $comment_link ) . $wp_rewrite->comments_pagination_base . '-' . $cpage;
$comment_link = user_trailingslashit( $comment_link, 'comment' );
$comment_link = add_query_arg( 'cpage', $cpage, $comment_link );
if ( $wp_rewrite->using_permalinks() ) {
$comment_link = user_trailingslashit( $comment_link, 'comment' );
$comment_link = $comment_link . '#comment-' . $comment->comment_ID;
* Filters the returned single comment permalink.
* @since 4.4.0 Added the `$cpage` parameter.
* @see get_page_of_comment()
* @param string $comment_link The comment permalink with '#comment-$id' appended.
* @param WP_Comment $comment The current comment object.
* @param array $args An array of arguments to override the defaults.
* @param int $cpage The calculated 'cpage' value.
return apply_filters( 'get_comment_link', $comment_link, $comment, $args, $cpage );
* Retrieves the link to the current post comments.
* @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
* @return string The link to the comments.
function get_comments_link( $post = 0 ) {
$hash = get_comments_number( $post ) ? '#comments' : '#respond';
$comments_link = get_permalink( $post ) . $hash;
* Filters the returned post comments permalink.
* @param string $comments_link Post comments permalink with '#comments' appended.
* @param int|WP_Post $post Post ID or WP_Post object.
return apply_filters( 'get_comments_link', $comments_link, $post );
* Displays the link to the current post comments.
* @param string $deprecated Not Used.
* @param string $deprecated_2 Not Used.
function comments_link( $deprecated = '', $deprecated_2 = '' ) {
if ( ! empty( $deprecated ) ) {
_deprecated_argument( __FUNCTION__, '0.72' );
if ( ! empty( $deprecated_2 ) ) {
_deprecated_argument( __FUNCTION__, '1.3.0' );
echo esc_url( get_comments_link() );
* Retrieves the amount of comments a post has.
* @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is the global `$post`.
* @return string|int If the post exists, a numeric string representing the number of comments
* the post has, otherwise 0.
function get_comments_number( $post = 0 ) {
$post = get_post( $post );
$comments_number = $post ? $post->comment_count : 0;
$post_id = $post ? $post->ID : 0;
* Filters the returned comment count for a post.
* @param string|int $comments_number A string representing the number of comments a post has, otherwise 0.
* @param int $post_id Post ID.
return apply_filters( 'get_comments_number', $comments_number, $post_id );
* Displays the language string for the number of comments the current post has.
* @since 5.4.0 The `$deprecated` parameter was changed to `$post`.
* @param string|false $zero Optional. Text for no comments. Default false.
* @param string|false $one Optional. Text for one comment. Default false.
* @param string|false $more Optional. Text for more than one comment. Default false.
* @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is the global `$post`.
function comments_number( $zero = false, $one = false, $more = false, $post = 0 ) {
echo get_comments_number_text( $zero, $one, $more, $post );
* Displays the language string for the number of comments the current post has.
* @since 5.4.0 Added the `$post` parameter to allow using the function outside of the loop.
* @param string $zero Optional. Text for no comments. Default false.
* @param string $one Optional. Text for one comment. Default false.
* @param string $more Optional. Text for more than one comment. Default false.
* @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is the global `$post`.
* @return string Language string for the number of comments a post has.
function get_comments_number_text( $zero = false, $one = false, $more = false, $post = 0 ) {
$comments_number = (int) get_comments_number( $post );
if ( $comments_number > 1 ) {
$comments_number_text = sprintf(
/* translators: %s: Number of comments. */
_n( '%s Comment', '%s Comments', $comments_number ),
number_format_i18n( $comments_number )
* translators: If comment number in your language requires declension,
* translate this to 'on'. Do not translate into your own language.
if ( 'on' === _x( 'off', 'Comment number declension: on or off' ) ) {
$text = preg_replace( '#<span class="screen-reader-text">.+?</span>#', '', $more );
$text = preg_replace( '/&.+?;/', '', $text ); // Remove HTML entities.
$text = trim( strip_tags( $text ), '% ' );
// Replace '% Comments' with a proper plural form.
if ( $text && ! preg_match( '/[0-9]+/', $text ) && str_contains( $more, '%' ) ) {
/* translators: %s: Number of comments. */
$new_text = _n( '%s Comment', '%s Comments', $comments_number );
$new_text = trim( sprintf( $new_text, '' ) );
$more = str_replace( $text, $new_text, $more );
if ( ! str_contains( $more, '%' ) ) {
$comments_number_text = str_replace( '%', number_format_i18n( $comments_number ), $more );
} elseif ( 0 === $comments_number ) {
$comments_number_text = ( false === $zero ) ? __( 'No Comments' ) : $zero;