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:
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.
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*;Now in your theme’s
comments.php
;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 onWalker_Comment
if$wp_query::max_num_comment_pages
is empty. But providing you callwp_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;
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!
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 byget_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.You might want to play around with
Walker_Comment
in wp-includes/comment-template.php.