The code below is meant to simply loop through posts, give the opportunity to add html formatting to them, then return them to the shortcode position. I have conditional logic which defines formatting based on the passed in "category"(term). I need to output it twice on the same page, but I only see code that I've added outside of the loop.

function generate_my_shortcode_content($atts){
    $a = shortcode_atts( array(
        'post-count' => 3,
        'category' => 'default-cat'
    ), $atts );

    $post_count = (int)$a['post-count'];

    $post_category = explode(',', $a['category']);

    $args = array(
        'post_type' => 'my-type',
        'posts_per_page' => $post_count,
        'tax_query' => array(
                'taxonomy' => 'my-taxonomy',
                'field'    => 'slug',
                'terms'    => $post_category

    $test = "<h1>";

    $query = new WP_Query( $args );

        $post_id = get_the_ID();
        $post_title = get_the_title($post_id);
        $post_content = get_the_content($post_id);

        $posts .= $post_id . $post_title . $post_content;
        $test .= "this is a test";


    $test .= "</h1>";
    return $posts . $test;

This function will return {Post ID}{Post Title}{Post Content}<h1>this is a test</h1> on the first execution, but will only return <h1></h1> on the second. Why is this?

  • What do you mean by "second execution"? The second time you refresh the page? Mar 8, 2017 at 19:41

2 Answers 2


Not sure I understand what you are doing with your shortcode, but I think you need to run rewind_posts() to move the loop counter back to the beginning for the second "execution." Example here: https://codex.wordpress.org/Function_Reference/rewind_posts

further explanation here: https://stackoverflow.com/questions/23729847/wordpress-difference-between-rewind-posts-wp-reset-postdata-and-wp-reset-q


Try not messing with the global $post a WP_Query doesn't need to call the_post() to loop over the posts.

$query = new WP_Query( $args );
if( $query->have_posts() ):

    foreach( $query->posts as $post ):

        $post_id = $post->ID
        $post_title = get_the_title($post_id);
        $post_content = get_the_content($post_id);

        $posts .= $post_id . $post_title . $post_content;
        $test .= "this is a test";



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.