Combining shortcode and get_template_part

I manage a wordpress site and have created a template part that I usually paste below the content.

    <div class="posts-group">

        <h2>Featured store products</h2>

        <?php $catquery = new WP_Query( 'post_type=product&posts_per_page=4&orderby=rand' );
        while($catquery->have_posts()) : $catquery->the_post();
        ?>
        <a href="https://wordpress.stackexchange.com/questions/213705/<?php echo get_post_meta($post->ID,"PRODUCT-url', true);?>">
            <article class="post home-post homeproduct">
                    <div class="post-thumbnail-img">
                        <?php the_post_thumbnail('small-thumbnail'); ?>
                    </div>
                    <h2><?php the_title(); ?></h2>              
                    <p></p>
            </article>
        </a>

        <?php endwhile; ?>

</div>

Now I’m trying to put this IN BETWEEN the content, so I thought of using a shortcode

function get_products($atts) {
get_template_part('block-products-inline');
}
add_shortcode('products', 'get_products');

Now every time I post [products], I expect the products to go there.
However when I try the code above, the products template_part goes all the way to the top of the page, right underneath the title and right before the actual content.

But when I edit the shortcode to simply return some text, then the text DOES appear in the middle of the content.

Does anyone understand what’s going on? Because I don’t..

1
1

Try this

function get_products($atts) {
  ob_start();
  get_template_part('block-products-inline');
  return ob_get_clean();
}
add_shortcode('products', 'get_products');

Little explanation

php just outputs your content right away when its see print statement. What we do here is, we are holding all the output in buffer and not giving it in print until the whole things finish.

then we are returning the final whole results(outputs). This gives control on our side to when and where to print outputs.

You can even assign it to in variable and return them when needed

  ob_start();
  get_template_part('block-products-inline');
  $output =  ob_get_clean();
  //now you can return the output whenever you want with $output

Leave a Comment