The end-callback
of wp_list_comments()
One way is to use the end-callback
argument in:
wp_list_comments( [
'end-callback' => 'wpse_comments_ads_injection',
... other arguments ...
], $comments );
in addtion to your other wp_list_comments
arguments, by defining:
function wpse_comments_ads_injection( $comment, $args, $depth ) {
static $instance = 0;
$tag = ( 'div' == $args['style'] ) ? 'div' : 'li';
echo "</{$tag}><!-- #comment-## -->\n";
if ( 0 === $instance % 2 ) {
echo "<{$tag} class=\"comment__ad\">YOUR AD HERE!</{$tag}>";
}
$instance++;
}
where we do the counting with the static variable $instance
that’s incremented for each call.
This should inject the defined comment ads, using either div
or li
tags, depending on the styling.
By using the end-callback, we don’t need to modify the comment callback, if we don’t need to, just to inject the ads. So if we need the default comment layout, we can also inject the ads this way.
One could additionally use the comment depth
to control the ads display.
Note that the callback for both the callback
and end-callback
of wp_list_comments()
, has three input arguments, not four.
The wp_list_comments_args
filter
We can then adjust it further and use the wp_list_comments_args
filter:
add_filter( 'wp_list_comments_args', function( $args ) {
if ( ! isset( $args['end-callback'] ) ) {
$args['end-callback'] = 'wpse_comments_ads_injection';
}
return $args;
} );
instead of modifying the the wp_list_comments()
directly.
We can create a plugin for this or add this into the functions.php
file in the current theme’s directory.
Introducing injection’s offset, rate and html
Then we can add a support for the injection’s rate, offset and html:
add_filter( 'wp_list_comments_args', function( $args ) {
if ( ! isset( $args['end-callback'] ) ) {
// Modify this to your needs!
$args['end-callback'] = 'wpse_comments_ads_injection';
$args['_ads_offset'] = 0; // Start injecting after the 1st comment.
$args['_ads_rate'] = 2; // Inject after every second comment.
$args['_ads_html'] = '<img src="http://placekitten.com/g/500/100" />';
}
return $args;
} );
where we adjust the end-callback with:
/**
* Inject Ads To WordPress Comments - end-callback for wp_list_comments().
*
* The Ads HTML is sanitized through wp_kses_post().
*
* @version 1.0.11
* @see https://wordpress.stackexchange.com/a/328155/26350
*/
function wpse_comments_ads_injection( $comment, $args, $depth ) {
static $instance = 0;
$tag = ( 'div' == $args['style'] ) ? 'div' : 'li';
$ads_rate = isset( $args['_ads_rate' ] ) && $args['_ads_rate' ] > 0
? (int) $args['_ads_rate' ]
: 2;
$ads_offset = isset( $args['_ads_offset' ] ) && $args['_ads_offset' ] > 0
? (int) $args['_ads_offset' ]
: 0;
$ads_html = isset( $args['_ads_html' ] )
? wp_kses_post( $args['_ads_html' ] )
: '';
echo "</{$tag}><!-- #comment-## -->\n";
if ( $ads_offset <= $instance && 0 === ( $instance - $ads_offset ) % $ads_rate && ! empty( $ads_html ) ) {
echo "<{$tag} class=\"comment__ad\">{$ads_html}</{$tag}>";
}
$instance++;
}
Here’s a gist for the code to add into the functions.php
file in the current themes directory.
This is untested, but I hope you can adjust this to your needs!