Support

Account

Home Forums General Issues ACF not showing on page after custom function

Solved

ACF not showing on page after custom function

  • Hello everyone,
    I have have a problem after this function below, once I put the short code in the page all ACF fields after it do not show up. I have tried using wp_reset_postdata() and wp_reset_query(). Can someone please take a look at the function and tell me what I need to change to have the rest of the ACF fields show up after the functions short code on the template page.

    function wpb_recentpostsbycategory() {
    $the_query = new WP_Query( array( 
        'category_name' => 'blog',
    	'posts_per_page' => 4 
    ) ); 
      
    if ( $the_query->have_posts() ) {
        while ( $the_query->have_posts() ) {
            $the_query->the_post();
    		$image = get_field('blog_image');
    		if( $image ) {
    			$url = $image['url'];
    			$title = $image['title'];
    			$alt = $image['alt'];
    		}
    		if(empty($alt)) {
    			$alt = $image['title'];
    		}
        			$string .= '<div>';
    				if(get_field('blog_image')) {
    						$string .='<a href="' . get_the_permalink() .'" rel="bookmark"><img src="' . $url . '" alt="'.$alt.'" /></a>';
    					};
    					if(get_field('title')) {
    						$string .='<h4>' . get_field('title') . '</h4>';
    					} 
    					if(get_field('blog_listing_page_summary')) {
                            $short = strip_tags(get_field('blog_listing_page_summary'));
                            preg_match('/^(.{0,100})\b/u', $short, $matches);
    					    $string .= '<p>'.$matches[1].'<a href="' . get_the_permalink() .'" rel="bookmark">... Read More ></a></p>';
    					};
    				$string .= '</div>';
                }
        } else {
    }
    return $string;
    	
    	
    wp_reset_query();
    }
    
    add_shortcode('recentPosts', 'wpb_recentpostsbycategory');

    Thanks any help would be great!

  • Firstly you should be using wp_reset_postdata() after your loop instead of wp_reset_query(), but in the end you have a bigger issue than this and this does not matter and either should work if not for the bigger issue. See my explanation further down.

    Another issue is the you are not defining the global $post in your function and without doing this calling $the_query->the_post(); does nothing. But again, this does not matter because of the bigger issue.

    The bigger issue I’m thinking that you have is multiple nested queries.

    Both of the functions wp_reset_postdata() and wp_reset_query() always reset the query to the main WP query (global $wp_the_query).

    What does this mean.

    
    // there is always a "main query" and loop
    while(have_posts()) { // this is the loop of the "Main Query"
      .. etc
      {
        // somewhere a nested query is done, call this "Query #2"
        {
          // your shortcode is here and does another query
          // you call wp_reset_postdata() or wp_reset_query() 
          // query is reset to "Main Query" and NOT to "Query #2"
          // this means that any thing that still needs to be done for the
          // loop and post associated with the first nested query will be
          // looking at the wrong query and post
        }
      }
    }
    

    There are a few ways that this can be corrected.

    The first is to know the variable name of the other query object that is done and since you are inside a function that other variable will need to be in the global scope. For instance if that other query object variable name is $some_other_query then you can to the following to reset to that query

    
    global $some_other_query;
    $some_other_query->reset_postdata();
    

    Since it is likely that you cannot know the query you are nested in this option is probably impossible.

    The second way to do this is considered a hack and it may or may not work depending on the conditions. This involves saving the global $post value before you do your query and resetting the global post after you do your query.

    
    global $post;
    $saved_post = $post;
    { Do your query }
    // reset the original post
    $post = $saved_post;
    setup_postdata($post);
    

    The last way would be my preferred method. Instead of trying to use a basic loop and the_post() you loop over the result array and use the $post->ID

    
    // modify your loop
    if (!empty($the_query->posts)) {
      foreach ($query->posts as $post) {
        // use $post->ID to get values
        // for example
        $image = get_field('image', $post->ID);
        $permalink = get_the_permalink($post->ID);
      }
    }
    
  • Thank you John Huebner for your detailed explanation, I got it working!

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.