WordPress 2.7 Comment Callback Function

By Jeremy Clark
Filed In wordpress  |  Tagged , , , ,  |  4,079 views
TOP del.icio.us digg

WordPress With WordPress 2.7 coming closer and closer, I’ve been doing more work on some of the new features and implementing them in my themes. I’ve got the comments and pings separated, now I wanted a little more control of how the new comment loop displayed my comments. Namely the avatar being to small and arranging the comment meta data differently. So after a couple of days I’ve got it working using the comment callback feature. Basically you define how the comment loop pieces fit together. I’ll continue below to post the actual code.

The heart of the code is put into a themes functions.php file, if one doesn’t exist then simply adding one will suffice. This is how my comment code looks but if you look most of the pieces are from the old way the comments were displayed and the code is the same.

<?php function custom_comment($comment, $args, $depth) {
       $GLOBALS['comment'] = $comment; ?>
<li <?php comment_class(); ?> id="li-comment-<?php comment_ID( ); ?>">
<div id="comment-<?php comment_ID( ); ?>">
       <div class="avatar_cont"><?php if ($args['avatar_size'] != 0) echo get_avatar( $comment, $args['avatar_size'] ); ?></div>
Comment by <em><?php comment_author_link() ?></em>:
<?php if ($comment->comment_approved == '0') : ?>
<em>Your comment is awaiting moderation.</em>
<?php endif; ?>
<br />
<small class="commentmetadata"><a href="#comment-<?php comment_ID() ?>" title="">
<?php comment_date('l, F jS Y') ?> at <?php comment_time() ?></a>&nbsp;|&nbsp;<?php edit_comment_link('Edit','',''); ?></small>
	<?php comment_text() ?>

<?php echo comment_reply_link(array('before' => '<div class="reply">', 'after' => '</div>', 'reply_text' => 'Reply to this comment', 'depth' => $depth, 'max_depth' => $args['max_depth'] ));  ?>
</div>
<?php } ?>

The biggest headache I had was with the comment reply link, I was looking at some older pre beta 2 code and some of the options had since been changed.

After getting the code into the functions file it’s necessary to tell the comment loop to use these directions for displaying. Editing the wp_list_comments function like below will call the custom template.

<?php wp_list_comments('callback=custom_comment'); ?>

Notice the custom_comment is the same as the function name in the first block of code, this is how it’s identified.

Thanks to Otto for pointing this out:
Instead of hardcoding the avatar size the callback code will now pull out the size that you specify in the wp_list_comments arguments. As an example this would produce a avatar size of 48 while still using the custom callback.

<?php wp_list_comments('avatar_size=48&callback=custom_comment'); ?>

Thanks to Jan Dembowski for pointing out a problem with the comment form box not showing up in the right place when replying to comments. The code above reflects the change necessary to fix the problem. By adding this

<div id="comment-<?php comment_ID( ); ?>">

and then closing the div before the end of the function the comment form will now show up right underneath the comment being replied to instead of under all the children comments.

1 Star2 Stars3 Stars4 Stars5 Stars |  (6 votes, average: 4.83 out of 5)
Loading ... Loading ...

46 Comments

  • 11

    Hi there, i’ve just loaded the theme you created, Techozoic and i’m having an issue with the comments.

    Fatal error: Call to undefined function function_exisits() in /…/…/…/…/…l/aoshi/wp-content/themes/techozoic-fluid/comments.php on line 152

    What can i do to fix this error?

  • 12

    I’m having exactly the same problem as above.
    Fatal error: Call to undefined function function_exisits() in /home/——-/wp-content/themes/techozoic-fluid/comments.php on line 152

    Awesome template, but bit useless for a non-techy like me, please help :-)

  • 13

    Jeremy,

    Do you know how to get the comment “Leave a Reply” box to appear within the comment’s … ? When I click on the Reply to this comment link it appears outside of that comment’s .

    Thanks,

    Jan Dembowski

  • 14

    Nuts, the formating got removed… The comment reply box is appearing outside of that comments LI … /LI tags.

  • 15

    I have downloaded and installed your latest Techozoic theme and have a question… how do I get the total number of comments to appear in a bubble just like you do on your website. Right now the total comments are printed in text.

  • 16

    Hi Jeremy.
    Can you let me know how i insert line breaks into my posts using your theme?

    One posted, my txt all bunches together with no returns, cheers, dwyz

  • 17

    Many thanks for this, just what I was looking for. :)

    Just a quick comment, on line 13, you need to move the vertical line surrounded by two non-breaking space into the code of “edit_comment_link”, so that the vertical line only appears if you’re logged in.

  • 18

    Hey Jeremy,

    I had a question about this. I’m also trying to fix my threaded comments to put in some custom stuff, and I’m running into a couple of issues I can’t seem to make work. My biggest one is wrapping the comment replies in a singe div. (meaning, if a comment has “children”, I want to basically capture ALL the children in one big div under the parent comment.)

    Now, I have figured out how to do the parent/child relationship, but my issue is that the comment Loop is not setting the outer div once – instead it’s setting it for every child comment.

    Do you happen to know of a way to “pause” the comment loop within the function, to output that since opening/closing div tag? Right now, I’ve got it figure out that when the first instance of a child is discovered, I can place in the divs – I just don’t want them to repeat for every *instance* of a child – just open on the first and close on the last. Got any tips on that front?

    (great tutorial by the way! :) )

  • 19

    I got it :) Well, I’m more than halfway there anyway. I just needed this in my function:

    $child = get_comment_class( $args );
    $child = $child[has_children];
    if($child == ’1′ ) {
    echo ” . “\n”;
    }

    So now if this comment is a parent, it’ll stick in a div. Still trying to get the arrangement correct, but at least figuring that out got my a lot farther ahead than I was :)

      • :) Well, I *did* – but it turned out the extra effort was for naught. It turns out I needed to do something that is beyond the scope of my knowledge for PHP – and I’m currently trying to sort it. I was “taking the long road,” when apparently there was a much easier method – but since inserting code into WP core functions is beyond my PHP scopr of knowledge, I was stuck.

        if you’re interested (I’m not asking you to solve this for me, but if you’d like to direct me to a clue, that would be awesome :) )basically the core code (in the comments-template.php file) holds “start_levl()” and “end_lvl()” functions, that hold case/breaks. The “div” case is actually what I need to insert code into. The “ol” and “ul” cases both have ID’s attached to them, but I needed an extra line added to the “div” case. My issue is on *how* to add that extra line *without* editing core code (i.e. using my functions.php file to insert the extra info).

        I still haven’t gotten that figured out – but when (ir if – I don’t even know if this is possible) I do, I’ll post it back here.

        • That’s out of my league as well. But if you do find a solution I’d like to post it here for others who want the same layout.

          • Well, I got it. Whether or not it’s a *great* solution, I dont’ know. Someone with more PHP knowledge than I could probably pull it off in less lines of code than I did.But the way I see it is 1) it works and 2) I’m not hacking core files anymore.

            BECAUSE it’s so many lines of code, I’m not going to post the entire thing here, but I did promise I’d come back and tell you if I succeeded, and because I like to share what little knowledge I have that resides in my brain, I’ll give you snippets of how (because seriously, it’s a lot more code than I’m comfortable placing on someone else’s site!)

            Basically, what I needed was PHP’s “extend” for classes. In the comments-template.php file, the “Walker_Comment” class needed to be overwritten. Problem is, it’s a pretty big class, so you have a lot of code to overwrite. Basically everything from line 1128 all the way down to the end. The GOOD news is, all I had to do was rewrite a few of those lines. Because you’re extending a class, this will override the current one in core – so you’re not repeating functions (and getting that horrid “cannot redeclare” error.

            So here’s what lines I overwrite:

            1128 is “class Walker_Comment extends Walker {”

            I renamed the class so now it reads “bb_class Walker_Comment extends Walker {”

            1154 – 1156 says:

            switch ( $args['style'] ) {
            case ‘div’:
            break;

            I changed that to say:

            switch ( $args['style'] ) {
            case ‘div’:
            echo “Show/Hide Replies\n”;
            echo “\n”;
            break;

            1178-1180 says:

            switch ( $args['style'] ) {
            case ‘div’:
            break;

            that was changed to this:

            switch ( $args['style'] ) {
            case ‘div’:
            echo “\n”;
            echo “\n\n”;
            break;

            Line 1279 says:

            function wp_list_comments($args = array(), $comments = null ) {

            I changed that to:

            function bb_list_comments($args = array(), $comments = null ) {

            and finally, line 1354 says:

            $walker = new Walker_Comment;

            I changed that to call in the new class:

            $walker = new bb_Walker_Comment;

            Now, in your comments.php file (in your theme) instead of calling “wp_list_comments” you call in “bb_list_comments”. All the same functionality, etc applies (even your tutorial above).

            By adding the jQuery library into my header.php file, and calling the show/hide display, now my comments will expand by clicking the “show/hide replies” link. If you want to see it in action, you can go to my site (trying NOT to put in a shameless plug here, but maybe if people see what I was trying to do, it’ll help):

            http://brassblogs.com/blog/wordpress-27-and-comment-display

            scroll to the bottom, and the last comment has a “Show/Hide Replies” link. Click it and see what happens.

            The awesome thing is, by rewriting said class, it’ll go as many levels deep as you like. My site’s set to go three levels deep, but I haven’t had anyone reply to a reply yet, so you can’t see the effect – but on my localhost install I have it 5 levels deep with a bunch of test comments, and it goes down for every single level. So awesome.

            Hope that helps someone out :)

          • And by the way, I’m probably going to post the full code on my own site so people can use it (I don’t mind using up my OWN server space!) – you mind if I link back here as well? (Actually this might be better as a plugin rather than a function, I think I’ll see if i can’t pull that off…) To show people how to do the remote callback stuff?

            I should also mention that pagination *should* work too – you’re not messing with anything except basically adding divs, but I haven’t tried the pagination thing to see what effect it has.

          • Feel free to link here, and let me know when you get the page up with the code and I’ll link to it. I might be using that code, I really like the show/hide replies feature.

  • 20

    Okay, I’ve uploaded it here:

    http://brassblogs.com/lab/expandable-comment-replies

    Turned it into a plugin. The post is partially finished – I need to tweak it, and I’m also going to add it to the WordPress Extend area – but there you go.

    Thanks! :)

Trackbacks / Pingbacks

Leave a Reply

Want an Avatar like seen here. Sign up for Gravatar

Subscribe without commenting