1

I want to display a default featured image if there hasn't been one set. I googled for a solution and all I could find was this piece of code (below). My question is, is there a way of displaying a default image by writing a function inside the functions.php? I don't want to repeat myself with the code.

<?php if ( has_post_thumbnail() ) {
the_post_thumbnail();
} else { ?>
<img src="<?php bloginfo('template_directory'); ?>/images/default-image.jpg" alt="<?php the_title(); ?>" />
<?php } ?>
2

The relevant code is in wp-includes/post-thumbnail-template.php. The thumbnail ID is stored in post metadata as _thumbnail_id.

You could either

  1. upload the default image to WordPress and make its ID the default thumbnail ID for any post that doesn't have one:

    function default_post_metadata__thumbnail_id( $value, $object_id, $meta_key,
                                                  $single, $meta_type )
    {
        if ( '_thumbnail_id' == $meta_key )
        {
            $value = 123; // the ID for the default image
        }
        return $value;
    }
    add_filter( 'default_post_metadata', 'default_post_metadata__thumbnail_id', 10, 5 );
    

    This means that has_post_thumbnail() and get_the_post_thumbnail() will now find a thumbnail for the post even if one isn't configured, and will just work as normal with the given ID, i.e. find the correct image size and generate the image tag for you etc.

    However I'd guess there's a risk this ID would be saved into a post when you edit it, so you possibly want to only register the filter if if (! is_admin() ) {, i.e. on the front-end site only. And this does mean you'll need to add the image to the media library, although it might be possible to fake that too e.g. by using ID -123 and hooking image_downsize_default_thumbnail to return an image for -123.

  2. override the has_post_thumbnail filter to always return true, and override the post_thumbnail_html filter to fill in missing HTML if it returns an empty string.

    function default_post_thumbnail_html( $html ) {
        if ( $html == '' ) {
            return sprintf("<img src=\"%s\" alt=\"%s\" />",
                esc_url( bloginfo('template_directory') . '/images/default-image.jpg' ),
                esc_url( get_the_title() ) );
        }
        return $html;
    }
    add_filter( 'post_thumbnail_html', 'default_post_thumbnail_html', 10, 1 );
    add_filter( 'has_post_thumbnail', '__return_true' );
    

    This way you have to generate the <img> completely yourself, but this will let you use an image that doesn't have an ID.

5
  • I tried solution one and that was a perfect solution! Another question came to mind while using that. Instead of the ID of the image, is it possible to set a title to be the featured image? Sep 28 '20 at 7:52
  • You mean text instead of an image? I don't think so, no, at least not with the current code. You could some variation of the second solution here to output different HTML instead of an image.
    – Rup
    Sep 28 '20 at 11:43
  • No, I mean I upload an image with the name "feature-img" and want that to be displayed (instead of checking what the ID is and changing the new ID in the code). That way I would only need to update the title of the new featured image. Sep 28 '20 at 11:46
  • Oh, sorry. You can probably use get_page_by_title( 'feature-img', OBJECT, 'attachment' )->ID - that will read the whole post from the database when you just want the ID here, but then WordPress will need to read the whole post later to display it I'd expect, and it would be cached on read, so that's no problem.
    – Rup
    Sep 28 '20 at 15:52
  • ... or there are some other ideas here; How to find attachment by its name?
    – Rup
    Sep 28 '20 at 16:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.