Seems like you've already got it working from our comments in your other answer (which you can probably just mark as accepted if you're using the approach), but just for your own reference, here's how you might be able to fix your field template approach.
Per your comment mentioning that your initial implementation in the field template was breaking comment_reply_count module, I think it's because of your structure. If you look at https://git.drupalcode.org/project/comment_reply_count/-/blob/8.x-1.x/js/comment_reply_count.js, it relies on $(this).parents('article.comment').next().slideToggle();
. This line tries to toggle the element directly after article.comment, which is normally <div class="indented">
. Since you're rendering your ad div after the comment, I'd wager that it's trying to toggle that instead.
To maintain the functionality, I think you'd need to:
- Determine whether a given comment is a parent comment or a child/indented comment. Comments keep track of this on the
pid
value, which stands for Parent ID. If the PID is empty, it's a parent comment. Comments have a hasParent()
method that checks this.
- If it is a parent, then render the ad before the comment if it is divisible by 3 (or 4, or whatever).
{% set parent_comment_counter = 0 %}
{% for key, item in comments if key|first != '#'%}
{% if key != 'pager' %}
{% if not item['#comment'].hasParent() %}
{% set parent_comment_counter = top_level_comment_counter + 1 %}
{% if top_level_comment_counter is divisible by(3) %}
<div class="ads">{{ drupal_entity('block_content', '5') }}</div>
{% endif %}
{% endif %}
{% set item = { '#pre_render': pre_render, 0: item } %}
{{ item }}
{% else %}
<div class="comment-pager">{{ item }}</div>
{% endif %}
{% endfor %}
If you wanted to do this in preprocess instead, you could do something like
hook_preprocess_field__comment_forum(&$variables) {
$parent_comment_counter = 0;
foreach($variables['comments'] as $k => $comment_item) {
if(!is_array($comment_item) || !isset($comment['#comment'])) {
continue;
}
$variables[$k]['show_ad'] = false;
/** @var Drupal\comment\Entity\CommentInterface $comment_entity */
$comment_entity = $comment['#comment'];
if($comment_entity->hasParent()) {
continue;
}
$parent_comment_counter += 1;
$variables[$k]['show_ad'] = $parent_comment_counter % 3 === 0;
}
}
in which case your template could then look like
{% set parent_comment_counter = 0 %}
{% for key, item in comments if key|first != '#'%}
{% if key != 'pager' %}
{% if item.show_ad %}
<div class="ads">{{ drupal_entity('block_content', '5') }}</div>
{% endif %}
{% set item = { '#pre_render': pre_render, 0: item } %}
{{ item }}
{% else %}
<div class="comment-pager">{{ item }}</div>
{% endif %}
{% endfor %}
That's the gist of it. You'd need to modify it if you wanted to include the ad around indented comments to ensure that you aren't including the ad block above the first indented comment after a parent, as that would break it in the same way as before.
I'm not sure exactly why <div class="comments_ajax_pager_wrap">
was disappearing, though. That wrapper is added by comment_ajax_pager_entity_display_build_alter(), so maybe you could debug from there.