0

What I'm trying to achieve is spreading related posts throughout the content - such as one reccomendation after every 3 paragraphs.

As I see it, three things need be done:

1 - Do the loop. What I'm using now is something like this:

<?php
$related = new WP_Query( array( 'post__in' => $whatever) );
if ( $related->have_posts() ) {
    while ( $related->have_posts() ) {
        $related->the_post();
        get_template_part('relatedpost');
    }
}
wp_reset_query();

2 - Split the post - I'm using this code, that works great for static content such as ads.

function insert_related_post( $text )
{
    if ( is_single() ) :
        $insert = '[ad]';
        $split_by = "</p>";
        $insert_after = 3; //number of paragraphs
        // make array of paragraphs
        $paragraphs = explode( $split_by, $text);
        $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 ? $insert : '' ) . $paragraph;
            // increase index
            $i++;
        }
        return $new_text;
    endif;
    echo $text;
}
add_filter('the_content', 'insert_related_post');

3 - Insert each element in the loop after every third paragraph. That, I can't figure how to do.

I suppose that the iterations should look something like this...

<?php
$related = new WP_Query( array(
    'post__in'       => $whatever,
    'posts_per_page' => '1',
    'offset'         => $i++/3,
) );

if ( $related->have_posts() ) {
    while ( $related->have_posts() ) {
        $related->the_post();
        get_template_part('relatedpost');
    }
}

wp_reset_query();

...but I can't manage to have that work - so where/how could I put it?

1

You can buffer the template part to use it within post content:

<?php
add_filter( 'the_content', 'add_related_each_nth_p' );

function add_related_each_nth_p( $content )
{
    if ( ! is_single() ) {
        return $content;
    }

    // the interval between added content
    $paragraph_steps = 3;

    // declare empty output
    $output = '';

    // declare related posts offset
    $z = 0;

    // make the array of paragraphs
    $content = explode( '</p>', $content );

    // iterate through the content paragraphs
    for ( $i = 0; $i < count( $content ); $i++ ) {

        // concatenate paragraphs one by one
        $output .=  $content[ $i ] . '</p>';

        // check if interval is reached and if so, concatenate related
        if ( 0 == $i % $paragraph_steps ) {

            // run your query
            $related = new WP_Query( array(
                'post__in'       => $whatever,
                'posts_per_page' => '1',
                'offset'         => $z,
            ) );

            // related post offset increments by one every interval
            $z++;

            if ( $related->have_posts() ) {
                while ( $related->have_posts() ) {

                    $related->the_post();
                    // start buffering
                    ob_start();
                    get_template_part('relatedpost');
                    // concatenate related post to the output
                    $output .= ob_get_contents();
                    // Clean the output buffer
                    ob_end_clean();
                }
            }
            wp_reset_query();
        }
    }

    return $output;
}

Or you can move relatedpost template part markup to the function (see the appropriate place in the code above), for example:

<?php
if ( $related->have_posts() ) {
    while ( $related->have_posts() ) {
        $related->the_post();
        $output .= '<p>Related: ' . get_the_title() . '</p>';
    }
}

The code is not tested, though.

  • Thanks, it works fine, putting everything where it should be. I still have a bit of trouble as it ignores my custom loop and just gets the latest posts instead, but I suppose that's probably just an issue with my code or some reset that I need to put in somewhere. – Lucian Davidescu Feb 24 '18 at 18:02
  • Solved by putting it in a template instead of functions.php, for me it's just as fine. – Lucian Davidescu Feb 24 '18 at 19:56
  • Yes, the template is a good idea. – Max Yudin Feb 25 '18 at 8:23

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.