Nested comments ignored for max per page in wordpress

I have the default setting (IIRC) of 10 comments per page, and max nesting of 5 deep.

The problem (or at least, minor annoyance) is that replies to comments are not counted towards that maximum of ten per page. I can understand that you do not want to break a thread, and that should be avoided, but in my test case I have:

Read More
test10
- test10 2
- test10 3
- - test10 4
- - - test10 5
- - test10 6
- test10 7
- test10 8
- test10 9
test9
test8 (should be on a new page?)
test7
test6
test5
test4
test3
test2
test1

They all show on the same page. But in reality I want to break that after the test9 comment.

I have a funny feeling it’s not going to be easy. Hopefully there will be a method just within the theme framework, but I’m not afraid to modify wordpress if needs be.

Related posts

Leave a Reply

3 comments

  1. Since I decided this would actually be pretty damn useful for myself too, I pushed on and wrote a custom walker, Walker_Paged_Threaded.

    I’ve tried to comment to the best of my ability, and admittedly it’s a little thrown together, but I’m happy with the result.

    How To Use It

    The class is written with the same abstract approach as the original Walker, so as not to limit it to just comments. However, to keep things simple, we’ll rename it*;

    Walker_Comment_Paged_Threaded extends Walker_Comment
    

    Now in your theme’s comments.php;

    wp_list_comments( array( 'walker' => new Walker_Comment_Paged_Threaded ) );
    

    Wahey! Paged comments that account for threading.

    Known Side Affects

    Since we’ve changed the way pages are calculated, functions like get_comment_pages_count will start to behave abnormally when passed parameters like $per_page or $threaded. Out-of-the-box though, this is not the case.

    However, get_comment_pages_count will still fallback on Walker_Comment if $wp_query::max_num_comment_pages is empty. But providing you call wp_list_comments first, it’ll run the walker and set the property automatically.

    If you are displaying comment pagination or page links before your comments, you’ll need to do something like so;

    <?php
    
    /**
     * Capture comments in an output buffer. The function needs to run before
     * displaying page links, as it runs the walker and then sets the
     * 'max_num_comment_pages' property on $wp_query.
     */
    ob_start();
    
    wp_list_comments( array( 'walker' => new Walker_Comment_Paged_Threaded ) );
    $comments_list = ob_get_clean();
    
    ?>
    
    <?php paginate_comments_links(); ?>
    
    <?php echo $comments_list; ?>
    

    This is actually the neatest way to get around it, trust me!

    *If you want to keep it abstract, without multiple copies for each intent, you could fake ‘multiple inheritance’, which is a little ugly.

    N.B. I thought best to add this as a separate answer, as it’s actually an answer!

  2. At first I was like “nu-uh”, but then I was like “oh yeah!” 😉

    What’s great is all the ‘pagination’ is done in PHP. In other words, it’s just foreach loops and nested arrays, not SQL limits and offsets.

    The real meat of the work can be pinned down to Walker::paged_walk() (specifically, about half-way in through the method).

    Essentially, it loops over the comments and stacks them by their parent, then calculates which slice of the ‘top level’ set to show (based on the $page_num and $per_page args). Then it simply loops over this ‘slice’, also looping the comment children (if it has any).

    It can and shall be done! All it needs is a good mind to apply that same logic, but bring nested comments into the picture too. Whether that’s me or not is another question!

    But I thought I’d post this now, just to shed some light on the matter, and hopefully keep the ball rolling.

    N.B. There’s also another method, Walker::get_number_of_root_elements(), which is used only by get_comment_pages_count() (at least in core). However, this function is used everywhere, so despite what the method name implies, it would need to accommodate the new algorithm and encapsulate children too.