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.
—
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/)
$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 towp_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()
loadsheader.php
which should be where the header hooks fire. That means that code beforeget_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 beforeget_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.
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