Note: There’s an updated method for this that doesn’t require you to modify core theme files. Check out the link at the bottom of the article.
It’s been around five years since WordPress introduced threaded comments in 2008 allowing viewers of a blog to reply to comments with indentation instead of having a “flat” structure. This allows us to follow a discussion or debate between two people without having to move up and down the page repeatedly. WordPress also allows us to set the indentation level giving us a hard limit to the number of nested replies we can have. Unfortunately if we want infinite replies, we run into one of two problems.
Too Many Nested Replies
The maximum level of indentation allowed is 10. If your WordPress theme is not designed properly, the nested replies would fall into smaller and smaller columns sometimes becoming unreadable with only one a few characters per line! What we want is to continue to allow people to reply without additional indentations.
No Reply Button
We run into another problem. When the indentation limit is reached, we can’t reply anymore. Before that, every comment has a “Reply” link at the bottom. But if you want to respond to a comment that has already reached the maximum indentation, you’ll be forced to either start a new comment thread altogether, or to click the “Reply” link of another comment above that.
This can be problematic because the other person may not receive a notification that you responded to them. Here’s what the lack of a “Reply” link looks like:
Infinite Replies without Indentation
Here’s the ideal situation: we set the indentation levels for the purpose of appearances. Given our blog theme and taste, we don’t want them to go beyond a certain limit. But the reply button should always be available. Any additional comments that are added on to one that is already at the max limit will inherit the indentation of the parent comment.
This mimics the way comments are handled on social networks like Facebook and Google+. They effectively have an indentation level of 2 and allow infinite replies. So how do we go about replicating this on WordPress? Normally you would expect some plug-in or the other to do this for you but so far I haven’t found any. So we’re going to have to delve into the code and make a small change on our own.
Modifying comment-template.php
It wasn’t easy for me to find out where the code for the reply button was being generated. After sniffing about in various files, I finally found it in the “comment-template.php” file. It’s located in the wp-includes folder. Use a text editor like Notepad++ to edit it. If you try and do so in basic Notepad, it’ll just be a jumble of characters without any structure. Notepad++ is by far one of the best and easiest programs to quickly modify a bit of general code.
As of WordPress 3.6.1, we need to delete two lines starting at line number 1044. Look for the following piece of code:
if ( 0 == $args['depth'] || $args['max_depth'] <= $args['depth'] ) return;
It’s located in the get_comment_reply_link function (big surprise!). As you can see, it checks to see whether the comment is at the maximum indentation level and if so, doesn’t return anything. Just delete these two lines, save the file, clear your cache, and voilà!
This simple change magically adds a “Reply” link to each and every comment on your blog regardless of indentation levels. Now you too can effortlessly replicate the format found on social networks but with the additional ability to setting the indentation level yourself. And that’s how you get infinite replies on WordPress threaded comments. Don’t forget to take a backup of comment-template.php in case something goes wrong!
Update: I’ve found a workaround that generates infinite “Reply” links for nested WordPress comments and doesn’t require core file modifications.
Thank you!! This did the trick!
In reply to Kim
Glad I could help :) . Just make sure to change it each time WordPress updates!
Thanks, saved me some research time, though now I have to see if I can figure out how to do the trick with a custom function/filter. May take it to Stack Overflow.
In reply to CK MacLeod
I think you can manage it with a custom function or filter that is tailored for each theme. But since so many of themes implement their own way of commenting, it won’t be a “one size fits all” solution. WordPress’s filter hook for get_comment_reply_link activates after the check for threading depth and not before :(
In reply to bhagwad
Hmmm… sure looks like it SHOULD be simple… Just comment out a couple lines, as you show – should be simple to re-produce…
If I knew how to change the value of $args[‘depth’], I could use a solution someone else happened to provide in relation to another question at SO. I’ll paste the whole thing, but the relevant portion is for ‘max depth’:
comment_reply_link(
array_merge(
$args,
array (
‘add_below’ => ‘comment-body’,
‘depth’ => $reply_depth,
// + 1 to offer always a reply link for a consistent UI
‘max_depth’ => $args[‘max_depth’] + 1,
‘before’ => ”,
‘after’ => ”
)
)
I tried adding a function to alter the values under get_comment_reply_link accordingly, but I’m not sure I had the syntax right.
Will try again later… If I understood it just a little better, I might be able to play with some more creative solutions for people who might like to start the thread over again at the left or the bottom, but linked to the last reply at “max” -depth, or who might even want to start traveling right back to left, then right to left, then left to right, and so on! You could have an “infinite” thread snaking down the comment column thousads of comments long! There are blogs I’ve frequented where that would happen…, and where certain conversations might still be going on if people didn’t get tired of scrolling up and hitting reply on an old comment…
Won’t bother you again until I’ve had a chance to concentrate on this again, and that might not be for a couple of days or longer, but I’m wondering now if array_merge can be used to substitute the “better” values when the reply link is called.
In reply to CK MacLeod
Let me know if you get a working solution. I’d be happy to post it on my blog with credits…
Interesting article; but really not a good idea to modify the core code, or the theme’s code. As you mention, your changes will disappear on an update.
If you want to add functionality to the core code, or to a theme, without having to worry about overwriting your changes on a core code or theme update, then you need to learn about ‘child themes’. The googles have lots of tutorials on that.
If you are modifying the core code, or the theme code, then you are doing it wrong.
IMHO.
In reply to RIck H
I know how to create child themes. I just wanted a solution that doesn’t depend on which theme I use. I want a solution that a person can blindly “copy/paste” without bothering about what their WordPress set up is like.
A child theme won’t help me with that unfortunately.
In reply to bhagwad
IMHO, telling someone to modify core files or theme files is not proper for someone trying to provide help and information. Anyone that needs to add functionality to their site *should* be using child themes.
Learning how do modify things *properly* is important.
And (as you probably know) using a Child Theme to put that function you want to modify in the Child Theme’s function.php will allow the user to properly make the change. And they won’t have to worry about things breaking when the next update comes around. All that is required is to copy the function out of the core or theme files, then put that in the Child Theme’s functions.php file. Then they can modify the code any way that is needed.
There is even a great plugin that will create the child theme files for you. https://wordpress.org/plugins/child-theme-wizard/ . Works great!
But, and again IMHO, ‘teaching’ users to modify core files is not proper.
In reply to RIck H
I get the benefits of child themes – I really do :)
But like I said, sometimes you just want a quickfix solution without bothering your head too much. I think my disclaimers at the top of the article in bold should be enough to let people know what they’re getting into. We’re all adults no? We can make informed decisions for our own websites.
Personally, I’ve changed themes lots and lots of times. And this particular solution is heavily theme dependent. I really wouldn’t be in the mood to learn the ins and outs of each new theme or theme framework. Too much pain and effort.
There are never any absolutes, and there are times when breaking the rules is ok provided you know exactly what you’re doing. In certain situations, I believe this approach of mine by modifying the core files is appropriate.
WordPress can resolve this problem easily by changing their code to put the filter hook at the end of the “comments_reply_link” function instead of at the beginning. But till that happens, there is no universal solution to this.
I provide the “plug’n play” fix, I display the warnings. The rest is up to the users to implement or not as they see fit don’t you think?
In reply to bhagwad
I will still have to disagree. If you are going to tell people how to change something that is in the core code (or theme code), then the best way is to tell them to use a child theme to change something. If you have to point them to a tutorial on child themes, then do so.
But I believe that it is irresponsible to tell people to change core code. Even with disclaimers.
Changing core code is not recommended by the WordPress codex, and should not be recommended by anyone else. If anyone says to ‘just change this core code to fix things’, even with disclaimers, that is not being a responsible developer or a person that advises others via their blog.
Any developer that recommends changing core code, or does that for their clients, is not doing ‘best practice’. And if that were my developer doing that, I would be looking for someone else.
IMHO.
And that’s all that I need to say on this subject. Your blog, your topics, your recommendations. But irresponsible, and not a developer that I need to take advice from.
IMHO.
In reply to RIck H
I guess we disagree. I don’t subscribe to the “responsibility” theory. I’m providing a solution, with all disclosures. People are adults, and I am treating them as such. I do not believe in “hiding” a solution merely because of some dubious notion of “responsibility”.
I like tech. I like solutions. I won’t hold back ideas from people as if they’re kids who need to be protected.
In reply to bhagwad
(odd “proxy publisher failure” on last attempt to post this comment, followed by a commenting too fast warning… will see if it works this time…)
In reply to CK MacLeod
test
(weird – happened again am going to try this comment in smaller chunks)
I agree more with bhagwad than with Rick H here, though I certainly recognize his concern. The fact remains that replacing the function or two functions in comment-template.php is more complicated than copying those functions and pasting them into a child theme’s functions.php file. For users or developers who need the functionality in order to complete a project, but, for whatever reasons, limitations in coding skills or time or money, they will ALWAYS – in the real world – go with a workable hack over notional “right way to do it.” On the other hand, for developers who are capable of doing it right, knowing that a hack works will point them directly to what they need to do. In that case, posts like these would be at a minimum time-saving. I wouldn’t have known that “saving” the comment reply link was so easy as commenting out or deleting those two lines.
rest of comment I’ve been trying to post:
Unfortunately, taking Rick’s advice literally – copying the function, pasting it into child/functions.php, and changing it – will produce a fatal cannot re-declare function error. If Rick really wants to keep people from violating WP’s pristine core for lack of a better alternative, he should provide that alternative – which may be a very simple filtering process, but one that, I confess, stumped me the first time I looked at this problem, meaning that, if I were asked by a blogger to produce this feature today, I would employ the hack, hoping that, when I had time to focus on the problem and shore up my lack of knowledge, I could solve it, or, even better, that someone else had found the solution somewhere in the meantime.
When I posted this issue at StackExchange in December, it was generally ignored – whether because no one had an answer or because I explained it poorly, I can’t say. If Rick really knows how to get this accomplished, then I am sure that both bhagwad and I would be very grateful to be filled in.
In reply to CK MacLeod
My advice (to use a child theme and put the function in the functions.php) wasn’t meant to be taken literally. It was meant to caution against modifying core code. Doesn’t matter your opinion of the core code. If you are a responsible developer, and choose to be responsible in sharing information that is helpful, then advising to replace core code, even with a ‘this will be overwritten with an update’, is not responsible. Again, IMHO.
As for the process of properly creating and using a child theme, there are many tutorials on how to do that — the googles will find tons of them. Your best bet, assuming that you want to be a responsible developer, is to start with the guidance in the WordPress codex.
If you have no desire to be a responsible and knowledgeable developer, but would rather ‘hack’ things to make them work, then fine…go for it. Sharing that technique of ‘hacking away at the code’ in an effort to educate others is not responsible sharing or teaching. Even with disclaimers of ‘this will break in the future if updates happen’. (And that disclaimer indicates that you are not responsible enough to have a web site that gets updates for security or other reasons.)
As for the proper technique, I am not going to go into detail. There is plenty of information out there. But the basics are:
– create a child theme (I have mentioned a nice plugin that will do that work for you)
– copy the comments.php from the parent theme, or the WordPress core code, into the child theme folder.
– modify the comments.php in the child theme as you require.
– test your child theme as needed
– make the child theme live
That, I submit, is the proper way to teach someone a nifty technique you have developed. You have then imparted wisdom in proper techniques, and your audience can learn from your imparted wisdom.
Anyone, developer or whatever, that just hacks away at the core code without caring about the consequences in the future, is not a developer that is worth using.
Again, all of this IMHO. Do what you want. “Damn the torpedoes, full speed ahead!” “Don’t bother me with the facts, my mind is made up!”
In reply to RIck H
I understand perfectly well how to use a child theme, Rick. You’re just lecturing, and not listening, which is at least as important a skill for a developer as any other including proper coding. No one is advocating heedless hacking. Your instructions would be useful to a beginner, but you do not appear to have anything to add on this very specific, intermediate to advanced level objective. Also, the file in question is not comments.php – a relatively small and simple file, frequently customized in themes of all types – but comment-template.php, which is a 2365-line mass of core functions. One alternative is in fact to create a new comment.php. Another is to create a comment “Walker.” A third is to write a filter. A fourth is to write a custom function. Any of all of them – and probably others – might work, but if you’re busy trying to make a living or getting a job done, which is what people who actually use these sites and have never heard of a WordPress core function care about, you might not have the time for exploring complicated dead ends or least-optimal solutions.
In reply to CK MacLeod
I’m not sure he has a solution (I may be wrong of course). He just seems to be repeating the same thing about child themes over and over.
Still holding out for a good solution though. I’m totally willing to publicize it and give full credits to anyone who can solve this elegantly without much hassle in a general and repeatable way.
In reply to bhagwad
To be clear, though, the initial solution would most likely take the form of a custom function to be added to a child theme’s functions.php file. Rick is right about that, but it almost goes without saying. Once found workable, the solution could be written into a plug-in that would apply across themes that employ WP’s basic commenting system or specifically exploit comment-template.php, and that have comment-nesting turned on. Ideally, the WP development team would see how logical the change is, and turn it into a switchable default in WP core – an observation which, come to think of it, may also help, since the value for max-depth is set in admin. That snippet in which max-depth is set as “max-depth + 1” for the comment reply link only might be useful there. I think when I next have a block of time to devote to this question, I’ll look into that.
Doing a little more research and experimentation recently, I think I now know the preferred method for achieving infinite comment replies. The method could, I believe, be adapted as a plug-in, or addition to functions.php, but, given the wide variation in commenting formats and systems in different themes, I’m not sure that would be the most desirable approach anyway, as I will explain.
The typical method would be to modify comments.php in your child theme, with a callback to a custom commenting function, as described here:
http://codex.wordpress.org/Function_Reference/wp_list_comments#Comments_Only_With_A_Custom_Comment_Display
The key argument that you would have to add would be in the “tag”/function comment_reply_link(), where you could add the snippet used in one of my earlier comments above ( originally found at StackExchange). A theme at one site I’m working on provides its own custom comment handler, and was easy to modify. The theme uses
comment_reply_link( array_merge( $args,array(
‘depth’ => $depth,
‘max_depth’ => $args[‘max_depth’],
) ) );
We achieve infinite in-place comment replies simply by adding “+ 1” to the second array key.
comment_reply_link( array_merge( $args,array(
‘depth’ => $depth,
‘max_depth’ => $args[‘max_depth’] + 1,
) ) );
Detailed explanations of the above code (i.e., why the variables work, why we use array_merge() and what specifically it does for us) are not provided in the WordPress Codex, which doesn’t even list “max_depth” among the accepted variables for comment_reply_link, but does show a format similar to the above in the example referenced and linked earlier.
Perhaps array_merge is used precisely because the comment_reply_link default values do no include max_depth, but I have not researched this guess yet. Bottom line: It worked fine. It is not a universal answer, but it doesn’t require hacking a core file.
The main difficulty in providing a universal answer will be the different ways that different themes will approach comments. Some will add very little to the default wp_list_comments(). Others will employ a callback to a function in the theme’s functions.php. as in the Codex example. Still others will use a separate template file to supply the function rather than a function in functions.php. (That’s how the theme that I tested handles its comments.) Of course, many blogs and sites these days use third party commenting system’s like Disqus or LiveFyre.
So, though I believe it will be possible to filter comment_reply_link() via a function or plug-in, adding the desired “max-depth” argument and re-producing your hack, I’m not sure it would be desirable to do so anyway. I may still try to trial-and-error and research it out on my own. I think I’ll also renew or re-pose my December StackExchange post on the off-chance one of the WP coders there will be able to answer a more focused version of the question, though, as I said, I think that in the short term and for most purposes, the modification of theme or child-theme files will be adequate, and even possibly preferable.
In reply to CK MacLeod
You know, you just gave me an idea. How about instead of trying to modify comment_reply_link like this, we simply remove it altogether? I’m talking about calling the comment_reply_link filter and returning a null value.
Now that it’s gone, we hook into the “get_comment_text” filter that contains the content of the comment. And then we simply create our own reply link appended to the end of the content. We have everything we need. We know the comment ID, we know the structure of the URL…
It’s totally doable! That would work right? It’s almost like cheating, but I think it should work on every theme…
What do you think?
In reply to bhagwad
My initial experiments were along those lines, but failed, though I was trying them at a lower level of understanding. Part of the problem is that comment_reply_link() consists of echoing get_comment_reply_link(). The entirety of the former (from https://core.trac.wordpress.org/browser/tags/4.1.1/src/wp-includes/comment-template.php#L0) is this:
1444 function comment_reply_link($args = array(), $comment = null, $post = null) {
1445 echo get_comment_reply_link($args, $comment, $post);
1446 }
So I tried removing both, and replacing them with a new sequence, one duplicating your hack, but, even if you get it right, you still have to go into the theme files, by whatever means, that call them. I think instead the “right” way to go about a “universal for all themes that use built-in WP comment functions approach” might have to be more surgical. I’m pondering now the possibility of substituting max-depth = max-depth + 1 in between admin options and get_comment_reply(), which is in effect what the above theme alterations do, but, if you have a better way, I’m all for it!
In reply to CK MacLeod
If you can manage to change the variables, let me know. I’ll work on replacing the reply link with a new one in the meantime. I’m pretty sure I can do it.
Proof of concept – you see on my blog that comment replies have a “in reply to [author]” link at the start of each comment? I managed to do that by attaching it to the comment text in the manner I just described.
I should be able to do the same at the bottom with a reply link.
In reply to bhagwad
Not sure when I’ll be able to get to it. You may also want to keep in mind the javascript file that makes sure your reply boxes show up where you want ’em – or maybe what you do won’t interfere at all. I’ll be very interested to see if you make more progress than I did at the end of last year.
http://wpseek.com/hook/comment_reply_link_args/#source
It’s right there asking for max_depth + 1 (and only, apparently, since WP 4.1!) Should be question only of adding the argument and supplying the required $comments and $post. Unfortunately for me, I do not know how to do that quite yet.
Added a question at StackExchange – feel free to barge in and add some buzz to it!
http://wordpress.stackexchange.com/questions/180545/filtering-comment-reply-links-comment-reply-link-args-for-infinite-replies-i
(Or correct any mistakes I made – also includes some info on a filter hook that I thought I mentioned here yesterday, but maybe forgot to submit.)
In reply to CK MacLeod
I actually managed to get my idea working, but am trying to streamline it a bit…
In reply to CK MacLeod
It’s working! The “Reply” link that you see right now under each comment is generated programmatically with a “plug n’ play” piece of code :D . I’ve also reverted the core change I’d made earlier!
In reply to bhagwad
Great and congratulations! So how’d you do it?
Will also be interesting to test under “different conditions,” and to see if it’s susceptible to further customizations.
I guess we’ll see if the StackExchanges provide an alternative way of going about it via a filter. You could also submit your solution as an “Answer,” which’ll boost your reputation if you’re on StackExchange or want to be.
In reply to CK MacLeod
Come to think of it, you could get two answers, or at least 1.5 answers for the price of one with this.
In reply to CK MacLeod
I’ll write an article about it and paste the code there in a couple of days :)
In reply to bhagwad
Can’t hardly wait.
In reply to bhagwad
Testing the email reply form, which didn’t seem to work last time, a few minutes ago, when I wrote to say I can hardly wait for you to show your work. (And am still wondering about the comment I thought I left yesterday.)
In reply to CK MacLeod
Ah, I just checked and it had gone into spam!
In reply to CK MacLeod
Here’s my solution: https://www.webhostinghero.com/adding-infinite-replies-in-wordpress/
In reply to bhagwad
Excellent – very simple and achieves the main or initial goal, in a framework somewhat easily transferable across themes.
That said, it’s still somewhat short of the ideal solution which would 1) bypass the Javascript problem (not sure how big of a problem it is, but still), 2) generally leave theme-dependent customizations untouched, and 3) really handle the column at max-depth in a “proper” way.
The third one is something we haven’t discussed in detail, and it may seem like a small thing at first, but, as I’ve noted briefly before, one better result for the “terminal” column would be, I think, if at that point it “de-nested”: Subsequent replies would appear chronologically, as in a typical non-nested thread, which at that point the nested thread will have become. When I first began thinking about this question, before I stumbled across your hack, I also considered modifying behavior in other ways: There are several possibilities here, including one I mentioned in my first comment at this thread (the snaking column, see above), but I’ll have to leave them to a later discussion.
I’ll also continue holding out hope for an approach utilizing the built-in filter hooks, though I would not be surprised if a more complex and to my mind more ideal solution would not end up requiring replacement of the built-in reply link as in your approach – plus possibly a new JS file, too.
In reply to CK MacLeod
Even though WordPress introduced comment_reply_link_args to filter the arguments, the relevant “apply filters” call in comment-template.php takes place after the check to see if the comment has reached max-depth. This means that the filter never gets a chance to be called at all if the maximum nested replies has been reached!
It seems very illogical to have it done this way. But anyway…such is life. Until that changes, I really don’t see how we can achieve the same thing using filters :( . We’d need access to the “args” variable even earlier and since it gets passed on directly from wp_list_comments (I tried following the trail!), it’s pretty much a dead end.
Unless of course, we’re in the mood to write a new walker class from scratch. Seems like overkill to me.
In reply to bhagwad
Hmm – if it’s as you say, maybe Core developers anticipated the filter hook being used in some other way than I’d like to use it.
Perhaps not overkill either way, though, if the end goal is more complete solution for nested commenting. Some day, if I ever have the time, I ‘d like to include it in a suite of comment thread improvements, but, as I’ve said, what you’ve done here is already a substantial step forward over default behavior, as for that matter is the more theme-dependent, but very simple, max-depth + 1 alternative, as anyone who has ever participated in an active extended discussion on a WP nested thread ought to be able to confirm. Scrolling all the way up a thread to find a comment to reply to in the middle of a heated, complicated discussion is ridiculous, while nesting is very useful on a busy blog with an active, diverse, and argumentative commenter community.