Using global $post; to get featured image for custom post via WP_Query

I’m using a site-wide function to add css to the <head> of the page pull in featured images of various as a responsive page background. It works great across the rest of my site but fails on a page where I’m calling posts from a custom post type using WP_Query. I think this is because WP_Query doesn’t use the standard loop, and my function uses global $post;.

Is there a way to adapt the WP_Query loop to work with the function? I need the featured image function to also work on the rest of my site, which uses the standard WP loop.

Read More

Here’s how I’m calling the custom posts:

<?php $port_query = new WP_Query( array(
    'post_type' => 'portfolio',
    'posts_per_page' => 1,
    'orderby' => 'rand'
) ); 
if ( $port_query->have_posts() ): while ( $port_query->have_posts() ) : $port_query->the_post(); ?>
    <div class="page-bkg responsive-bkg">
        // page content here
    </div>
<?php endwhile; wp_reset_postdata(); endif;

And the function to call responsive featured images, from functions.php:

function bkg_featured_image() {

// call the global post variable
global $post;

if ( has_post_thumbnail( $post->ID ) ) : // checks whether the post has the featured image set

// get the post thumbnail ID for the page or post
$post_thumbnail_id = get_post_thumbnail_id( $post->ID );

// store the image sizes in an array. You can also add your own image sizes with the add_image_size function
$img_sizes = array( 'thumbnail', 'medium', 'large', 'full', 'thumb480', 'thumb768', 'thumb1280', 'thumb1680', 'thumb2048' );

// grab the URL for each image size and store in a variable
foreach ( $img_sizes as $img_size ) {
    ${ 'img_src_' . $img_size } = wp_get_attachment_image_src( $post_thumbnail_id, $img_size );
}

echo '<style type="text/css"> 

    .responsive-bkg {
        background-image: url(' . esc_url( $img_src_thumb768[0] ) . ');
    }

    @media screen and ( min-width: 768px ) {
        .responsive-bkg {
            background-image: url(' . esc_url( $img_src_thumb1280[0] ) . ');
        }
    }

    @media screen and ( min-width: 1281px ) {
        .responsive-bkg {
            background-image: url(' . esc_url( $img_src_thumb2048[0] ) . ');
        }
    }

</style>';

   endif; // end if the featured image is set

} // end function my_featured_image

add_action( 'wp_head', 'bkg_featured_image' );

// (this function borrowed from http://s2webpress.com/responsive-featured-image-function-in-wordpress-themes/)

Related posts

Leave a Reply

2 comments

  1. $port_query->the_post(); should set the $post global. That isn’t the problem. The problem is that the you are trying to use $post before your secondary Loop runs (99% sure).

    You’ve hooked the bkg_featured_image() function to wp_head. wp_head runs in the header of the document, which, unless you are careful, will run before the other template code.

    If you think about how WordPress theme template loading works, you will realize that get_header() loads header.php which should be where the header hooks fire. That means that code before get_header() in a theme file can use those hooks successfully.

    The fix is to make sure your secondary loop runs before get_header(). $post should be set to the first post in those results and your code should work. That doesn’t mean you have to output the results before get_header(), which wouldn’t make sense. You just have to run the query.

    Of course, you only have the first post in the Loop by doing it this way.

  2. WP_Query does use $post. A full list of Methods and Properties can be found In the codex here. Are you sure that all your Portfolio items have featured images? you might want to use 'meta_key' => '_thumbnail_id', in the arg to make sure the random Portfolio has an image. you could also check in the template using

    if( has_post_thumbnail( $post->ID ) ) :
    
        <div class="page-bkg responsive-bkg">
        // page content here
    </div>
    
    endif;