Aggregate comments, with pagination

I want to build a page that would display all comments, regardless of which post they’re attached to. I also want that page to be paginated, since it’ll potentially have 10,000+ comments.


I’m not sure how to go about it, but here are some of the functions I’ve studied so far:

Read More
  1. get_comments – If no post_id is passed in, it’ll return all comments. However, I don’t see a way to paginate these (there are offset and number options to fiddle with, but that’s very tedious to do manually).

  2. wp_list_comments – The documentation on this is pretty bad, but the source code suggests that we can loop over all comments if used in conjunction with get_comments, by passing in the get_comments array as a second argument. This however would still use get_comments to actually… well, get the comments, and there seems to be no way to paginate that.

  3. previous_comments_link & next_comments_link – These seem to only work in conjunction with wp_list_comments (with no second argument).

  4. paginate_comments_links – Also looks like it only works with wp_list_comments (with no second argument).


What I’ve tried:

  1. Simply using the number argument in get_comments:

    $comments = get_comments(array(
        'status'    => 'approve',
        'number'    => '2'
    ));
    
    wp_list_comments(array(
        'callback' => 'my_rendering_function'
    ), $comments);
    
    paginate_comments_links();
    

    This does not display any pagination links.

  2. The method suggested here: Display latest comments on page with pagination

    $comments = get_comments(array(
        'status' => 'approve'
    ));
    
    wp_list_comments('per_page=2', $comments);
    
    paginate_comments_links();
    

    This doesn’t either work (it shows the first 2 comments, but no pagination). Also, I cringe at get_comments loading all comments into memory.


Question:

How can I paginate all comments?


P.S. I’m using WordPress 3.4.1 & PHP 5.3.2.

Related posts

Leave a Reply

1 comment

  1. Most likely, the main thing that you missed is that you must have “Break comments into pages” checked in the Settings Discussion Subpanel. The pagination functions require this to be set, as do the URL rewrites.

    Here’s a working, complete page template to do what you’re asking:

    <?php
    /*
    Template Name: All Comments
    See http://wordpress.stackexchange.com/questions/63770/aggregate-comments-with-pagination
    */
    get_header(); ?>
    
    <div id="content" role="main">
    
        <?php
        # The comment functions use the query var 'cpage', so we'll ensure that's set
        $page = intval( get_query_var( 'cpage' ) );
        if ( 0 == $page ) {
            $page = 1;
            set_query_var( 'cpage', $page );
        }
    
        # We'll do 10 comments per page...
        # Note that the 'page_comments' option in /wp-admin/options-discussion.php must be checked
        $comments_per_page = 10;
        $comments = get_comments( array( 'status' => 'approve' ) );
        ?>
        <ol start="<?php echo $comments_per_page * $page - $comments_per_page + 1 ?>">
            <?php wp_list_comments( array (
                'style' => 'ol',
                'per_page' => $comments_per_page,
                'page' => $page,
                'reverse_top_level' => false
            ), $comments ); ?>
        </ol>
    
        <?php # Now you can either use paginate_comments_links ... ?>
        <?php paginate_comments_links() ?>
    
        <?php # Or you can next/prev yourself... ?>
        <?php if ( get_comment_pages_count( $comments, $comments_per_page ) > 1 ) : // are there comments to navigate through ?>
        <nav id="comment-nav">
            <div class="nav-previous"><?php previous_comments_link( __( '&larr; Newer Comments' ) ); ?></div>
            <div class="nav-next"><?php next_comments_link( __( 'Older Comments &rarr;' ) ); ?></div>
        </nav>
        <?php endif; ?>
    
    </div><!-- #content -->
    
    <?php get_sidebar(); ?>
    <?php get_footer(); ?>
    

    If you didn’t want to globally enable comment pagination, it’s still possible, but it’s a minor headache because you’ll have to manually add the rewrites rules. Once you do that, you can fool WordPress into thinking that comment pagination is enabled via a simple filter,

    add_filter( 'pre_option_page_comments', '__return_true' );