Wordpress is of course made up of templates and the template parts that make up those templates. I know I can override the template parts - that's not what I'm trying to do here. I'm trying take the HTML generated by said template part and display it elsewhere.

How can I get the rendered HTML data from a template part for a given Page/Post ID and display it as part of another page, preferably as a shortcode? Here is an example.

Let's say that post with ID = 20 has comments I'd like to display on a separate page. I want to write a shortcode that does this:

-- locate comment data for the post with ID = 20

-- apply that ID to the template part .//templates/comments.php and store the rendered HTML in a shortcode

-- use my custom shortcode anywhere on my page to display it. Ultimately I would show the comments with a similar [comments id="20"]

I know I'm using "comments" here but it's just an example. This will have applications elsewhere, especially with WooCommerce for example where I want to show specific product attribute for a given product.

2 Answers 2


Use setup_postdata() to make the 'current post' any given post, then retrieve the template part before resetting post data back to the original post. Any template tags that depend on the current post in The Loop that are in the template part will refer to the post you have set up with that function.

function wpse_302305_shortcode( $atts ) {
    global $post;

    $atts = shortcode_atts( ['id' => 0], $atts );

    $post = get_post( $atts['id'] );


    if ( $post ) {
        setup_postdata( $post );
        get_template_part( 'path/to/template' );

    return ob_get_clean();
add_shortcode( 'template', 'wpse_302305_shortcode' );

When I am trying to do something like this, I will use ob_start() and ob_get_clean() to convert the resulting template part into a string that can be returned for the shortcode.

A common gotcha with shortcodes is if you ECHO the output it will output the content at the wrong time.

Next, you'll want to use include locate_template('template-name.php') so your variables are passed in the proper scope.

If you're trying to load in a template part directly, you can do something like this (this code is untested):

// [get_comment id=0]
function get_comment_shortcode($atts){
  $a = shortcode_atts([
    'id' => 0,
  ], $atts);

  if(!get_comment($a['id'])) return false; //Bail early if the comment doesn't exist
  $id = $a['id']; //reference this ID in your template to get the comment ID
  include locate_template('comment-template.php');
  $result = ob_get_clean();
  return $result;

add_shortcode('get_comment', 'get_comment_shortcode');

References: https://codex.wordpress.org/Function_Reference/locate_template https://codex.wordpress.org/Shortcode_API

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.