I have an ACF field for hero images called hero_image
. This field sits at the top of my single.php
page like so:
<?php /** * The template for displaying all single posts * * @link https://developer.wordpress.org/themes/basics/template-hierarchy/#single-post * * @package sitename */ get_header(); ?> <?php $post_id = get_the_ID(); // Required as outside the loop $image = get_field('hero_image', $post_id); if ($image) { echo '<div class="hero">'.wp_get_attachment_image( $image, 'hero').'</div>'; } ?> <div class="has-sidebar"> <div id="primary" class="content-area"> <main id="main" class="site-main"> <?php while ( have_posts() ) : the_post(); get_template_part( 'template-parts/content', get_post_type() ); the_post_navigation(); endwhile; // End of the loop. ?> </main><!-- #main --> </div><!-- #primary --> <?php get_sidebar(); get_footer(); ?> </div><!-- .has-sidebar -->
I’m using the $post_id
variable to fetch the field from outside the loop. The image loads as expected.
If an image hasn’t been uploaded for a post using the field, I’m expecting there to be no markup on the front-end. However, I still see the following:
<div class="hero"></div>
Why isn’t my if statement working when the field isn’t in use?
Advertisement
Answer
I did some further digging and found my problem.
I have two ACF fields hero_image
and thumbnail_image
. These are set to appear on all pages and posts including custom post types.
Looking at the header.php
file, here’s what I found:
<?php // Get post ID $post_id = get_queried_object_id(); // Hero image $hero = get_field('hero_image', $post_id); $hero_url = wp_get_attachment_url( get_field('hero_image', $post_id), 'hero'); ?> <?php if ( is_single() || is_archive() ): ?> <header id="masthead" class="site-header"> <?php else: ?> <header id="masthead" <?php if ($hero) { echo 'class="site-header has-background" style="background:url('.$hero_url.')"'; } else { echo 'class="site-header"'; } ?>> <?php endif; ?>
As you can see, I’m also using the variable $post_id
outside the loop. This prevented the second $post_id
variable working via single.php
.
I’ve renamed $post_id
in header.php to $post_id_outside_loop
. I’ve then used this variable via single.php
as it’s also outside the loop. This has solved the issue.
<?php /** * The template for displaying all single posts * * @link https://developer.wordpress.org/themes/basics/template-hierarchy/#single-post * * @package sitename */ get_header(); ?> <?php // $post_id_outside_loop is set via header.php $image = get_field('hero_image', $post_id_outside_loop); if ($image) { echo '<div class="hero">'.wp_get_attachment_image( $post_id_outside_loop, 'hero').'</div>'; } ?> <div class="has-sidebar"> <div id="primary" class="content-area"> <main id="main" class="site-main"> <?php while ( have_posts() ) : the_post(); get_template_part( 'template-parts/content', get_post_type() ); the_post_navigation(); // If comments are open or we have at least one comment, load up the comment template. if ( comments_open() || get_comments_number() ) : comments_template(); endif; endwhile; // End of the loop. ?> </main><!-- #main --> </div><!-- #primary --> <?php get_sidebar(); get_footer(); ?> </div><!-- .has-sidebar -->