I am developing a WordPress theme for which I would like each comment’s timestamp wrapped in in a <span> element for the sake of styling it with CSS rules. However, the wp_list_comments() function as I use it in my theme’s comments.php template does not seem to provide options to alter the HTML produced:
<ol class="comment-list">
<?php
wp_list_comments( array(
'style' => 'ol',
'format' => 'html5',
'short_ping' => true,
) );
?>
</ol>
which produces timestamps as such:
<time datetime="2015-12-21T19:09:49+00:00"> december 21st, 2015 on 19:09 </time>
How can I alter the function’s output to include a <span>element around each <time> element without altering core files?
I’ve tried looking at my theme’s functions.php, as well as WordPress wp-includes/comment.php and wp-includes/comment-template.php. None of them deal with the actual tag structure of the comment timestamps generated by wp_list_comments(), so there was nothing there for me to play with.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Here are some options on how we can override the native layout for each comment:
Approach #1 – Overriding start_el() with a custom walker
Let’s define our custom wpse comment format:
// Arguments for wp_list_comments()
$args = [
'style' => 'ol',
'format' => 'html5',
'short_ping' => true,
];
// Use our custom walker if it's available
if( class_exists( 'WPSE_Walker_Comment' ) )
{
$args['format'] = 'wpse';
$args['walker'] = new WPSE_Walker_Comment;
}
wp_list_comments( $args );
with a custom comment walker, that handles this new format (PHP 5.4+):
/**
* Custom comment walker
*
* @users Walker_Comment
*/
class WPSE_Walker_Comment extends Walker_Comment
{
public function start_el( &$output, $comment, $depth = 0, $args = array(), $id = 0 )
{
// Our custom 'wpse' comment format
if ( 'wpse' === $args['format'] )
{
$depth++;
$GLOBALS['comment_depth'] = $depth;
$GLOBALS['comment'] = $comment;
// Start output buffering
ob_start();
// Let's use the native html5 comment template
$this->html5_comment( $comment, $depth, $args );
// Our modifications (wrap <time> with <span>)
$output .= str_replace(
[ '<time ', '</time>' ],
['<span><time ', '</time></span>' ],
ob_get_clean()
);
}
else
{
// Fallback for the native comment formats
parent::start_el( $output, $comment, $depth, $args, $id );
}
}
} // end class
Note how we handle our custom comment format. We also reuse the start_el() method from the parent class for the native formats, by calling parent::start_el().
Also note that we use the output buffering in a similar way as the parent class.
Approach #2 – Overriding html5_comment() with a custom walker
We can also directly override the native Walker_Comment::html5_comment() method, in the following way:
// Arguments for wp_list_comments()
$args = [
'style' => 'ol',
'format' => 'html5',
'short_ping' => true,
'walker' => new WPSE_Walker_Comment,
];
wp_list_comments( $args );
where our custom walker class is in functions.php defined as:
if ( !class_exists( 'WPSE_Walker_Comment' ) ) {
/**
* Custom comment walker
*
* @users Walker_Comment
*/
class WPSE_Walker_Comment extends Walker_Comment {
public function html5_comment( $comment, $depth, $args ) {
// Place the modifications of the Walker_Comment::html5_comment() method here
}
}
// end of WPSE_Walker_Comment
} // end of '!class_exists' condition
Here we can store our modifications to the Walker_Comment::html5_comment() method. It’s rather long, so I didn’t add it here.
Approach #3 – Custom callback
Here we would use the callback attribute:
// Arguments for wp_list_comments()
$args = [
'style' => 'ol',
'format' => 'html5',
'short_ping' => true,
];
// Use our custom callback if it's available
if( function_exists( 'wpse_comment_callback' ) )
{
$args['format'] = 'wpse';
$args['callback'] = 'wpse_comment_callback';
}
wp_list_comments( $args );
where we define the wpse_comment_callback() to our needs.
/**
* Custom comment callback
*/
function wpse_comment_callback( $comment, $depth, $args )
{
// Modify the Walker_Comment::html5_comment() method to our needs
// and place it here
}
where we could start by simulating the Walker_Comment::html5_comment() method. But we must remember to replace all reference to $this.
There are other approaches avilable, but hopefully you can adjust these to your needs.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0