Display comments in homepage in WordPress

I had an interesting experience working with comments in WordPress. The task is display comments in homepage, like in Pinboard theme by Themify. It looked simple at first and I thought it can be done easily with wp_list_comments() but the truth is not like. In this post, I’m going to show a simple trick that solve this problem.

First, take a look at this screenshot to know exactly what I mean (note the arrow):

Pinboard-Comments

In homepage, within the loop, I tried use the following code to display comments:

while ( have_posts() ) : the_post();
    // Display post
    if ( have_comments() )
    {
        echo '<ol class="comment-list">';
        wp_list_comments();
        echo '</ol>';
    }
endwhile;

This code didn’t work. When I looked at the source code of wp_list_comments(), I seeed that the problem comes from WordPress query:

function wp_list_comments($args = array(), $comments = null ) {
    global $wp_query;
    // Code
    if ( null !== $comments ) {
        // Something
    } else {
        if ( empty($wp_query->comments) )
            return;
        // Code
    } 
}

The problem is 2nd parameter $comments, which is null by default. In the wp_list_comments() function, it’s checked and will be assigned to $wp_query->comments if it is null. In homepage and other archive pages, the query doesn’t take any comments from database (of course, it doesn’t know the post, of which comments are get), so $wp_query->comments is empty. Function returns and nothing happens. This problem only occurs when we’re are not in single post.

We can solve this by using a simple trick: pass the list of comments to wp_list_comments() function, which will be passed to $comments variable later. To get list of comments of a particular post we use get_comments() function. The code will look like this:

$comments = get_comments( array(
    'post_id' => get_the_ID(),
    'status' => 'approve',
) );
if ( !empty( $comments ) )
{
    echo '<ol class="comment-list">';
    wp_list_comments( array(
        'callback' => 'rw_archive_comment_callback',
        'type'     => 'comment',
    ), $comments );
    echo '</ol>';
}

Here I use a custom callback to display comments. Because comments are listed simple, no threaded, the callback function is not very complicated:

/**
 * Display comment in home & archive page
 *
 * @return void
 */
function rw_archive_comment_callback( $comment, $args, $depth )
{
    ?>
    <li>
        <div class="comment-author">
            <?php echo get_avatar( $comment, 30 ); ?>
        </div>
        <div class="comment-content">
            <?php printf( '<cite class="url fn n">%s</cite>', get_comment_author_link() ); ?>:
            <?php echo strip_tags( get_comment_text() ); ?>
        </div>
    <?php
}

That’s all for PHP. If you want to have the final result like Pinboard, you need to add some CSS. Because themes are different, I won’t paste my junky CSS here. But I hope you can understand the idea.

This trick is not hard to do. But it’s quite interesting for me because it makes me pay attention to a rarely used argument of wp_list_comments() function while I use it in every theme. The moment like this makes me think WordPress is really attractive.

5 thoughts on “Display comments in homepage in WordPress

  1. The Pinboard theme looks beautiful. I like the way they use Masonry to organize posts in the homepage. And your trick is awesome, too. Quite simple!

  2. This Pinboard looks awesome! I will use your experience for my new web site. Thank you for sharing this information.

  3. I used to search WP plugins for this task, but I am now very much surprised to see that its very much easy!

  4. You saved my hours if not days of searching! Figuring this out has been the biggest headache for the last 24 hours. Thank you so much for your advice!

Comments are closed.

Newsletter

Subscribe to our newsletter to receive news and tutorials about WordPress and web development.

Meta Box - Creating expert WordPress custom fields and custom meta boxes in minutes! Check it out →