Customising wp_list_comments()

WordPress 2.7 introduced a simplified way of listing comments with a new function called wp_list_comments() for use in a theme’s comments.php. This automatically takes care of the display of the author, date, avatar, comment text etc, rather than the more complex way used for older versions of WordPress. This is all fine and dandy, but actually makes customising the output of the comments – ie what exactly is displayed – slightly more complex.

wp_list_comments()

I’m not going to repeat all that can be found on the Codex, see wp_list_comments() for details, but essentially the function has a fairly limited set of arguments, none of which relate to some of the elements mentioned above. For example, it isn’t possible to exclude the comment date, or avatar, by playing directly with the function’s arguments.

Custom callback

Luckily, the WP developers saw fit to include the the use of a callback function within wp_list_comments(). The callback function is called like this:

wp_list_comments('type=comment&callback=mytheme_comment');

What this means is that wp_list_comments() will return the output of the callback function rather than it’s default output. So, to create our own customised output, we simply need to define a suitable callback function, in this example a function called mytheme_comment, in our theme’s functions.php.

And this is exactly what I have done on www.studiograsshopper.ch, where I use a custom callback function to display Trackbacks and Pingbacks differently from normal comments. You can see an example here.

If you look at the Trackbacks on the post linked above you will see that the display is simplified: there is no Reply button, and I’ve changed the default “Says” text to “Wrote”. There are some CSS tweaks too, but let’s ignore those for the moment.

Basically, if we were to run this function and view its output, we would see exactly the same result as the normal comments on this site. In other words, this function will produce the same output as the following code in a typical theme’s comments.php file:

<?php wp_list_comments('type=comment'); ?>

Now we have a base to work from, it’s not too difficult to edit this function to give us the output we want. In my case, I wanted to display Trackbacks and Pingbacks differently from normal comments.

Customising Trackbacks and Pingbacks

Let’s look at how I customised the theme on my site to achieve this.

First, I opened up my theme’s comments.php and found the wp_list_comments() used to display trackbacks and pingbacks:

<?php wp_list_comments('type=pings'); ?>

Note that type=pings covers both trackbacks and pingbacks.

I then added the call to my custom callback function to the existing code:

<?php wp_list_comments('type=pings&callback=custom_pings'); ?>

Then, in functions.php, I added the Codex example callback function, renamed it to custom_pings, then edited this function to remove the elements I didn’t want, in my case:

A final word – the Codex actually advises against using callback functions with wp_list_comments(), which seems odd given that the developers added this capability in the first place. I’ve been running this code for a while now, without problems, and have no hesitation in recommending the use of a callback function if you need maximum flexibility to control the output of wp_list_comments().

I don't think WP likes something in there, because when I upload the revised comments.php and functions.php, and then click on my website, nothing happens. I made sure that the callback in my comments.php file matches that in my functions.php file. The callback is:

The general effect I’m going for is this:

Josh Bales spake thusly on December 16th, 2009 at 2:12 pm:
I am a man of many mysteries.

I completely buggered up the above message with the code I included, so I just uploaded the message and relevant code to my site. It’s at http://joshbales.net/callbackcode.txt if you care to take a look.

The issue I’m having is that it feels a little heavy-handed for what I want to achieve. Essentially, I want to add a custom class to each comment IF the user is a logged-in administrator (which will act as a hook for some AJAXy fun to do with moderating comment karma). So I only want to add a class, rather than entirely replace the output of wp_list_comments().

Is there a better way to achieve this? Or do I just have to accept that I’ll need to write it all out again?

I basically copied and pasted ‘type=comment&callback=mytheme_comment’ to create wp_list_comments(‘type=comment&callback=mytheme_comment’); in my comments.php file and copied and pasted the exact sample code from the Codex into my function.php file (which currently does not have any other code).

I believe it was mentioned above by someone else, but I’m not sure the issue was resolved. Would anyone have any advice? Is there any other code from other files that may be affecting the code on functions.php?

Indeed, the callback works fine. The Codex is a Wiki, so anyone can put what they like in there. Perhaps, when wp_list_comments was first introduced, the callback function was a bit flaky, hence the Codex author’s comments. Works fine for me though.

When I arrived at this page, I had already been using the custom call back “successfully” ( aside from the li classes) but I was using the callback as it appears on wordpress.org, and in source, the comment “li”s had NO classes.

It finally occurred to me to switch to the callback code included with this article and all the comment “li” classes “came back”. This article was a huge help – thanks.

P.S. You should get your code to replace the code on the wordpress.org site.

This is an brilliant example of a proper work-through. It has a simple intro, a well-explained work-through and, most importantly, an excellent summary. I just wish other bloggers could write like this! Bookmarked for future reference. Thank you.

He told me to do it myself… I used your code up there to create two functions, one to output the one with highest rating and highlight it. The other to output all other comments. Guess I will put in the sorting later but it’s working fine.

The short answer is that you don’t. That ID is unique to each individual comment. You need to target the wrapper div which has an id of “comments” (note the plural), which is created by the main wp_list_comments() function.

More importantly, if you want to style author commnets differently to other users, is to look at the classes automatically added to the <li> tag of each comment. (Remember, the comment list is a “list”). Look at your Page Source and you’ll see what I mean.

Absolutely Fantastic! Was just about to throw in the towel with respect to gaining added control over wp_list_comments() and then found your post. It took a little bit to fully understand what was going on, but you hit the nail on the head. Thank You!

FYI, deploying this on WP 3.1.2 with a theme manager plug-in and the ‘custom comment’ plug-in because I want to gather — and thanks to you — report additional field-level data associated with Comments.

A “callback” is a function which is passed as an argument to another function.
In our example, the function custom_pings() is the “callback”. This needs to be placed in your functions.php.
To make it do something useful, this callback then has to be passed to the wp_list_comments() function (which probably appears in your theme template files), like this:wp_list_comments('type=pings&callback=custom_pings');

What do I do if I don’t have a comments.php file? I had a custom WP theme made for me but they never made a comment section, so I’m attempting to make one on my own. However, I’m not sure: Should I just make my own comments.php file or should I download another theme and try and take it from there? Any help would be appreciated, thanks!

About Studiograsshopper

WordPress plugins, coding and development tips and resources. I am available for hire for WordPress site development and customisation. This site is also my coding and CSS playground. So don't be surprised if it looks wonky from time to time!

Do not adjust your television…

Studiograsshopper is currently being overhauled, tweaked, polished and honed, thanks to a wonderful new child theme for the Genesis Framework courtesy of AppFinite. Unfortunately, this means that in the very short term, as I move and reconfigure content, certain things may look a bit weird or crocked in some way. Panic ye not! I'm fixing stuff as quickly as possible.