Using new WP_Query in shortcode in a custom field causes the main post content to not display

I’ve got a custom post type of files I’m trying to list using a new WP_Query.

It works fine when I add the shortcode within the main post content. However, when I add the shortcode to a custom field (which I have set to display on the page along with the main content as a secondary “column”), the main content disappears!

Read More

If I comment out the “while…have_posts()” and “endwhile” lines, the main content displays; however, even after commenting out every other line, the main content disappears unless I also remove the “while”.

I am pretty certain it has to do with using WP_Query (somehow it hijacks the loop), even though it shouldn’t.

Is there something I’m missing?

Here’s the shortcode:

   function ia_news_display_test($atts){ // [ia_news cat='category' num='numbertodisplay']

extract(shortcode_atts(array(
        'cat' => 'any',
        'num' => '2',
        ), $atts));

$dirloop = new wp_query( array( 
    'post_type' => 'ia_news', 
    'category_name' => $cat,
    'posts_per_page' => $num,
    'orderby' => 'menu_order',
    'order' => 'ASC'
));

if ($dirloop->have_posts()){
    $content = "<ul class='ia_news_list'>n";
    while ( $dirloop->have_posts() ) : $dirloop->the_post();
        $custom = get_post_custom($post->ID);
        $file_id = $custom["upload_file"][0];
        $file_begin = $custom["begin_date"][0];
        $file_end = $custom["end_date"][0];
        if ('' != $file_end){$file_end = " to ".$file_end;}
        $file_url = wp_get_attachment_url($file_id);

            if ('' != $file_url) { //CHECK FOR EXISTENCE OF FILE URL
               $content .= "<li class='ia_nl'><a href='".$file_url."'>".$cat." ".$file_begin.$file_end."</a></li>n";
            }
    endwhile;
    $content .= "</ul>n";
} else { $content = "nothing"; }

return $content;

}

Related posts

Leave a Reply

3 comments

  1. You’re using get_posts which returns an array of posts, which you can loop through using foreach, but not the_loop. Try this version of the code:

    function ia_news_display_test($atts){ // [ia_news cat='category' num='numbertodisplay']
    
    extract(shortcode_atts(array(
            'cat' => 'any',
            'num' => '2',
            ), $atts));
    
    $dirloop = new WP_Query( array( 
        'post_type' => 'ia_news', 
        'category_name' => $cat,
        'posts_per_page' => $num,
        'orderby' => 'menu_order',
        'order' => 'ASC'
    ));
    
        if ($dirloop->have_posts())
        {
            $content = "<ul class='ia_news_list'>n";
            while ( $dirloop->have_posts() ) : $dirloop->the_post();
    
                $file_id = get_post_meta(get_the_id(), "upload_file", true);
                $file_begin = get_post_meta(get_the_id(), "begin_date", true);
                $file_end = get_post_meta(get_the_id(), "end_date", true);
    
                if ('' != $file_end)
                {
                    $file_end = " to ".$file_end;
                }
                $file_url = wp_get_attachment_url($file_id);
    
                if ('' != $file_url) 
                {   
                    //CHECK FOR EXISTENCE OF FILE URL
                    $content .= "<li class='ia_nl'><a href='".$file_url."'>".$cat." ".$file_begin.$file_end."</a></li>n";
                }
            endwhile;
            $content .= "</ul>n";
        } 
        else
        { 
            $content = "nothing";
        }
        wp_reset_postdata();
    
        return $content;
    }
    
    add_shortcode('ia_news_test', 'ia_news_display_test');
    

    Also, if you’re custom field name is upload_file, then try using get_post_meta instead of taking a long cut as you’re code does.

  2. You should use wp_reset_postdata() before you return out of the function. Similar to wp_reset_query(), but restores the global $post instead of $wp_the_query.