0

I currently have some code that I am using to add a Custom Field (An advertisment) after 3 paragraphs as below:

//Insert ads after third paragraph of single post content.
function insert_ad_block( $text ) {

if ( is_single() ) :



    $ads_text = '<div class="center">' . get_field('blog_post_ad', 'option') . '</div>';
    $split_by = "\n";
    $insert_after = 3; //number of paragraphs

    // make array of paragraphs
    $paragraphs = explode( $split_by, $text);

    // if array elements are less than $insert_after set the insert point at the end
    $len = count( $paragraphs );
    if (  $len < $insert_after ) $insert_after = $len;

    // insert $ads_text into the array at the specified point
    array_splice( $paragraphs, $insert_after, 0, $ads_text );

    // loop through array and build string for output
    foreach( $paragraphs as $paragraph ) {
        $new_text .= $paragraph; 
    }

    return $new_text;

endif;

return $text;

}
add_filter('the_content', 'insert_ad_block');

This currently works well. However, I want to modify it so that it adds the same code EVERY 3 paragraphs. So if a blog post had 9 paragraphs, the ad would be shown after paragraph 3, 6 and 9.

I'm not too sure how to do this. Please help! :)

  • Try using a modulo. Basically you declare a counter, let's says $i = 0 and you loop through all your paragraphs and when $i % 3 == 0, you can insert your ad – Sladix Jan 18 '17 at 14:49
1

The easiest way I can think of is to go through the paragraphs adding the ad text along with your paragraphs:

function insert_ad_block( $text ) {

    if ( is_single() ) :

        $ads_text = '<div class="center">' . get_field('blog_post_ad', 'option') . '</div>';
        $split_by = "\n";
        $insert_after = 3; //number of paragraphs

        // make array of paragraphs
        $paragraphs = explode( $split_by, $text);

            if ( count( $paragraphs ) > $insert_after ) {

                        $new_text = '';     // new text
                        $i = 1;             // current ad index

                        // loop through array and build string for output
                        foreach( $paragraphs as $paragraph ) {
                            // add paragraph, preceeded by an ad after every $insert_after
                            $new_text .= ( $i % $insert_after == 0 ? $ads_text : '' ) . $paragraph;
                            // increase index
                            $i++;
                        }

                        return $new_text;
            }


            // otherwise just add the ad to the end of the text
            return $text . $ads_text;

    endif;

    return $text;

}
add_filter('the_content', 'insert_ad_block');

This script keeps track of which paragraph it is looking at with $i and appends the ad after every $insert_after. The index starts counting at 1 (not 0) to avoid opening the post with an ad. This script could use a bit of finessing.

As a sidenote, using line breaks can be a bit tricky in determining paragraphs, as it can introduce ads in the middle of lists, or put multiple ads on top of each other when the user is trying to space out items. For legibility, maybe its worth looking for </p> and running the filter very late (after wpautop). Its really a matter of balacing your business objectives with UX.

Hope that's what you are looking for :)

  • Thanks for this Pedro! It works, kind of! It does seem to include ANY break, even if the break is caused by an image or a title. It also counts bullet points as 1 para. Anyway of getting it to ignore them so it just counts the actual text paragraphs? – user2115227 Jan 19 '17 at 13:22
  • Maybe changing $split_by to </p> would do the trick? Or better, do the same as wpautopand look for two line breaks ( \n\n ), which should avoid splitting lists. A plugin I really like is Advanced Ads (br.wordpress.org/plugins/advanced-ads) It has an option of injecting ads in between paragraphs. You could dig through its source code to see how they do it. – Pedro Coitinho Jan 19 '17 at 18:27
  • Hugely useful - thanks again Pedro! I've marked your original answer as correct, as it does the job I asked :) – user2115227 Jan 20 '17 at 9:19
  • Any easy way to use succesive elements from an array with $ads_text? (I'm trying to use this in order to spread a query of related posts throughout the article.) – Lucian Davidescu Feb 21 '18 at 2:31

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.