Within PHP loop WordPress dynamic_sidebar() function is returning 1 instead of the content

Viewed 189

I have this custom function to show WordPress posts:

echo evertstrap_conditional_posts( [
    'numberposts' => 3,
    'category' => $term_id,
    'post_class' => 'horizental-post',
    'first_full_width' => true,       
    'thumb_size' => 'latest-thumb',                     
    'boostrap_class' => 'col-6 col-sm-6 col-md-12',
    'show_thumb_caption' => true,
    'read_more' => true,
    'ad_id' => $ad_id,
    'ad_loop_offset' => 2               
] );

This function code is like that:

<?php
function evertstrap_conditional_posts( $args = null ) {

    global $post;

    $default = array(
        'post_type' => 'post',
        'numberposts' => 10,            
        'bootstrap_class' => 'col-6 col-sm-12 col-md-12',           
        'thumb_size'    => 'thumb',
        'show_excerpt'  => true,
        'show_author'   => true,
        'first_full_width' => false,            
    );

    $args = wp_parse_args( $args, $default );
    $recent_posts = get_posts( $args );

    if( $recent_posts ) {

        $output = '';
            $read_more = isset( $args['read_more'] ) ? $args['read_more'] : '';
            $term_id = isset( $args['category'] ) ? $args['category'] : '';
            $class = isset( $args['bootstrap_class'] ) ? $args['bootstrap_class'] : '';
            $first_full_width = isset( $args['first_full_width'] ) ? $args['first_full_width'] : '';

            // For advertisement
            $ad_id = isset( $args['ad_id'] ) ? $args['ad_id'] : '';
            $ad_loop_offset = isset( $args['ad_loop_offset'] ) ? $args['ad_loop_offset'] : ''; // How many loop the ad should offset


            $counter = 1;
            foreach ( $recent_posts as $post ) {
                setup_postdata( $post );
                $post_id = get_the_id();

                //  some more code here......

                $output .= "<div class='{$conditional_bootstrap_class}'>";
                    $output .= '<article class="'.$conditional_article_class.'">';
                        $output .= '<div class="post-thumb">';                               
                        $output .= '</div>';

                        $output .= '<div class="post-meta">';                              
                        $output .= '</div>';                      
                    $output .= '</article>';
                $output .= "</div>";                    


                // Show advertisement on every 5 posts                  
                if( $counter % $ad_loop_offset == 0  ) {                        
                    $output .= '<div class="col-md-12">';
                        $output .= dynamic_sidebar( $ad_id );
                    $output .= '</div>';
                }

                $counter++;
                // Show advertisement on every 5 posts end here
            } // Foreach end here

        //$output .= '</div>'; // article wrapper class 
        wp_reset_postdata();
        return $output;         
    }
}

Now if you see this code:

if( $counter % $ad_loop_offset == 0  ) {                        
    $output .= '<div class="col-md-12">';
        $output .= dynamic_sidebar( $ad_id );
    $output .= '</div>';
}

Here, I want to show WordPress Dynamic Sidebar on every 2 loop. This $ad_id contains the id of the sidebar.

But it only returns 1 instead of the content between the loop :(

The actual content is showing above the whole loop :(

can you tell me why? and how can I solve it?

1 Answers

The dynamic_sidebar function is documented here and my read of it is that it outputs the sidebar as a side-effect, returning true or false depending on whether the sidebar can be found and called.

Based on that, you could use output buffering to avoid changing your code flow too much, like so:

if( $counter % $ad_loop_offset == 0  ) {                        
    $output .= '<div class="col-md-12">';

    // start output buffering to capture the output of `dynamic_sidebar`
    ob_start();

    // output the sidebar
    dynamic_sidebar( $ad_id );

    // get the contents of the output buffer
    $output .= ob_get_contents();

    // clean out the output buffer and turn off output buffering
    ob_end_clean();

    $output .= '</div>';
}
Related