The Walker_Comment class seems to be the weirdest and most hacked together of all the Walker classes in WordPress. Despite a few hours searching, I could not find a single example of a working Walker_Comment class anywhere on the entire internet. So I made this one from scratch by copying the default Walker_Comment function that comes with WordPress. It’s doing what I need it to, but I’m not 100% sure I’m using it properly.

Weirdness

Ignoring $output

Although the functions are set up to pass a global &$output variable forward, they don’t do it (at least in the default Walker class), they just echo each portion as it comes. It appears the Walker totally ignores the variable which just strikes me as odd.

start_lvl() Isn’t the Start

The start_lvl() function, with a $depth of 0 begins at each child comment, so essentially at the start of every reply which is the first to reach a new level under a particular comment. This took me awhile to figure out and is also rather odd. That’s why you have to wrap the comment list div/ol/ul yourself, because it has no way to reach the top of it’s own comments list. I was able to wrap the comment list dynamically by just using the constructor and destructor functions, but I’m sure none of the other Walkers require that.

Callbacks?

In the $args for wp_list_comments(), there are 2 optional callback functions which plug into start_el() and end_el() (I believe), so if you don’t need to play with any of the other functions, this is probably a less annoying way to accomplish this. I removed that plugged-in code from this example since there is no reason to ever do a custom Walker that refers to outside functions, just pick one or the other.

Anyway, here’s the code I finally came up with:

Code

Calling the Walker

You need to point wp_list_comments() to your walker function by including it in the walker argument. I just created a comments.php template file with the following code:

<div id="comments-container">
    <?php wp_list_comments( array(
        'walker' => new zipGun_walker_comment,
        'style' => 'ul',
        'callback' => null,
        'end-callback' => null,
        'type' => 'all',
        'page' => null,
        'avatar_size' => 32
    ) ); ?>
</div><!-- /#comments-container -->

<div id="respond-container">
    <?php comment_form(); ?>
</div><!-- /#respond-container -->

This will draw out comments and the response form.

Custom_Walker_Comment Function

/** COMMENTS WALKER */
class zipGun_walker_comment extends Walker_Comment {
    
    // init classwide variables
    var $tree_type = 'comment';
    var $db_fields = array( 'parent' => 'comment_parent', 'id' => 'comment_ID' );

    /** CONSTRUCTOR
     * You'll have to use this if you plan to get to the top of the comments list, as
     * start_lvl() only goes as high as 1 deep nested comments */
    function __construct() { ?>
        
        <h3 id="comments-title">Comments</h3>
        <ul id="comment-list">
        
    <?php }
    
    /** START_LVL 
     * Starts the list before the CHILD elements are added. */
    function start_lvl( &$output, $depth = 0, $args = array() ) {       
        $GLOBALS['comment_depth'] = $depth + 1; ?>

                <ul class="children">
    <?php }

    /** END_LVL 
     * Ends the children list of after the elements are added. */
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        $GLOBALS['comment_depth'] = $depth + 1; ?>

        </ul><!-- /.children -->
        
    <?php }
    
    /** START_EL */
    function start_el( &$output, $comment, $depth, $args, $id = 0 ) {
        $depth++;
        $GLOBALS['comment_depth'] = $depth;
        $GLOBALS['comment'] = $comment; 
        $parent_class = ( empty( $args['has_children'] ) ? '' : 'parent' ); ?>
        
        <li <?php comment_class( $parent_class ); ?> id="comment-<?php comment_ID() ?>">
            <div id="comment-body-<?php comment_ID() ?>" class="comment-body">
            
                <div class="comment-author vcard author">
                    <?php echo ( $args['avatar_size'] != 0 ? get_avatar( $comment, $args['avatar_size'] ) :'' ); ?>
                    <cite class="fn n author-name"><?php echo get_comment_author_link(); ?></cite>
                </div><!-- /.comment-author -->

                <div id="comment-content-<?php comment_ID(); ?>" class="comment-content">
                    <?php if( !$comment->comment_approved ) : ?>
                    <em class="comment-awaiting-moderation">Your comment is awaiting moderation.</em>
                    
                    <?php else: comment_text(); ?>
                    <?php endif; ?>
                </div><!-- /.comment-content -->

                <div class="comment-meta comment-meta-data">
                    <a href="<?php echo htmlspecialchars( get_comment_link( get_comment_ID() ) ) ?>"><?php comment_date(); ?> at <?php comment_time(); ?></a> <?php edit_comment_link( '(Edit)' ); ?>
                </div><!-- /.comment-meta -->

                <div class="reply">
                    <?php $reply_args = array(
                        'add_below' => $add_below, 
                        'depth' => $depth,
                        'max_depth' => $args['max_depth'] );
    
                    comment_reply_link( array_merge( $args, $reply_args ) );  ?>
                </div><!-- /.reply -->
            </div><!-- /.comment-body -->

    <?php }

    function end_el(&$output, $comment, $depth = 0, $args = array() ) { ?>
        
        </li><!-- /#comment-' . get_comment_ID() . ' -->
        
    <?php }
    
    /** DESTRUCTOR
     * I'm just using this since we needed to use the constructor to reach the top 
     * of the comments list, just seems to balance out nicely:) */
    function __destruct() { ?>
    
    </ul><!-- /#comment-list -->

    <?php }
}

Summary

Now there is at least 1 custom Walker_Comment function on the internet :).

6 Thoughts on “Custom Walker to Extend the Walker_Comment Class

  1. Hi ! Nice one ! You helped me build a custom walker comment class for my Bootstraped theme ! If you want to check it out, it’s right here : https://github.com/haroldparis/origines

  2. Hi! Many thanks for alt comments script and ready-to-use form! I have a one question: i’v put title of my comments in function __construct(); Title is:

    Comments

    , But in case comments are disabled in page, i can see this title. How can i fix it? Thank you!

  3. Hi! Many thanks for alt comments script and ready-to-use form! I have a one question: i’v put title (in h2 tags) of my comments in function __construct(); But in case comments are disabled in page, i can see this title. How can i fix it? Thank you!

  4. Ok, i’ve fixed it. Put wp_list_comments( ) after if ( comments_open( $post_id ) on comment-template.php

    Thank you anyway!

  5. Hi

    can I use your custom walker to output wp_list_comments() into a variable? If not what do I need to change? Or even better can you think how I can output native wp_list_comments() into a variable? I don’t understand classes :-( so I am totally lost here. Thank you. R

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation