1

I am showing comments on my page. I want to show 1 ad after every 2 comments.

<div class="panel-ads clearfix"></div> it's repeating the number of comments.

I would like to add the ad code after every 2 comments.

For example:

<div class="panel-ads clearfix"></div>
<div class="panel-ads clearfix"></div>

/*
 * My ads code
 */

<div class="panel-ads clearfix"></div>
<div class="panel-ads clearfix"></div>

/*
 * My ads code
 */

My wp_list_comment() function: (function.php)

<?php
function new_comment($comment, $args, $depth,$i=0) { 
    $GLOBALS['comment'] = $comment;
    $PostAuthor = false; 

    if($comment->comment_author_email == get_the_author_email()){
        $PostAuthor = true;
    }elseif($comment->comment_author_email == 'user@example.com'){
        $PostAuthor = true;
    } 
?>

<div class="panel panel-default entry" id="comment-<?php echo $comment->comment_ID; ?>">
    <div class="panel-body">
        <div itemprop="text">  </div>
    </div>
    <div class="panel-footer clearfix">
       <?php comment_text(); ?>
    </div>
</div>

<?php 
}
  • Your code example isn't very clear - where are you looping through your comments? – phatskat Feb 8 at 23:16
  • I use this function to bring comments to another page. I updated the top. can you please look? – batuhan Feb 9 at 0:53
3

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!

  • I tried to understand, but I didn't. I updated the top. can you please look? this is really pushing me. I've been looking for solutions on all platforms for 1 week. @birgire – batuhan Feb 9 at 0:55
  • I updated the answer with a filter approach to make it easier to modify things like rate, offset and html, I hope it helps, if not I see you're on a good track with @phatskat answer +1. – birgire Feb 9 at 9:30
  • Birgire, you're amazing. but it's complicated. my English is not enough to understand it. what codes do I have to add? and where do I add it? I know this much. but I can't help it. sorry man. – batuhan Feb 9 at 10:01
  • First I would recommend having a local test install to play with. You can e.g. add the code to your functions.php file in the current theme's directory. I created a public gist for you here: gist.github.com/birgire/493f0d646491532e0ed5b0c5549f1a12 – birgire Feb 9 at 10:15
  • 1
    great job. you're incredible. tried this. thanks. +1 @birgire – batuhan Feb 9 at 11:43
1

Give this a shot, let me know if you have any questions.

<?php
function sinyor_comment($comment, $args, $depth,$i=0) { 
    /**
     * This follows @birgire's answer, hat-tip for use of `static`.
     *
     * The `static` keyword declares `$count` as static to the
     * `sinyor_comment` method. That means that it will persist
     * within the function's scope on each run of `sinyor_comment`.
     *
     * Essentially: $count will always be what you set it to the
     * last time you called `sinyor_comment`, which you can use
     * to tell which comment you're on.
     */
    static $count = 0; // This assignment only happens the first time.

    // Not sure what you're using this for, but I would recommend
    // finding a better way to pass this around if you need
    // it elsewhere.
    $GLOBALS['comment'] = $comment;

    $PostAuthor = false; 

    if($comment->comment_author_email == get_the_author_email()){
        $PostAuthor = true;
    }elseif($comment->comment_author_email == 'user@example.com'){
        $PostAuthor = true;
    }
?>

<div class="panel panel-default entry" id="comment-<?php echo $comment->comment_ID; ?>"  itemprop="suggestedAnswer" itemscope itemtype="http://schema.org/Answer">
    <div class="panel-body">
        <div itemprop="text">  </div>
    </div>
    <div class="panel-footer clearfix">
       <?php comment_text(); ?>
    </div>
</div>
<?php

    // If we haven't had two comments, don't show the ad.
    if ( 2 > $count ) {
        // Increment $count by 1.
        $count++;
        return;
    }

    /**
     * Your Ad Code
     */

    // Reset count to zero.
    $count = 0;
}
  • hahaha. this work. but he adds the ad after the third comment. I want to add after the first comment. – batuhan Feb 9 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.