How do I get images (with a thumbnail preview) to show in search results?

The Short Version

I’ve constructed a WordPress site (Gazette theme base) with lots of image media. All have descriptions, captions, and titles but do not show up in search results; using Relevanssi I could get their title and description to appear, but no image was shown! How do I get image media to appear in search results with image thumbnails?

Context:

I’ve built a product portfolio website for a blacksmith. Each page has multiple image galleries: for example, “Custom Pieces” has various types of knives, swords, and other pieces with unique names, “Axes” has various standard axes he produces, and so on. Because customers might be looking for something of a particular description without knowing where it lives they’ll likely do a lot of searching. I’ve found, however, that WordPress’s default search isn’t very helpful and completely excludes image media. If I search for “Damascus”, for example, I would get zero results despite having dozens of images with Damascus in the caption, description, and title! I installed Relevanssi, which causes all of the relevant media to show up in search results, but none of the images are actually displayed:

enter image description here

If the search finds any Post, Page, or other item with a featured image, then the image thumbnail appears. Since images don’t (appear) to have that field, I don’t know how to make them display a thumbnail. I simply don’t know the WordPress API well enough to know where to look or what to do. What PHP calls do I need to make those images appear, or is there a plugin that does exactly what I’m looking for? (I’m not a web developer, but I do have a software engineering background and some basic web experience.)

Thanks in advance!

1 Answer
1

This is something that will need to be handled in the search results template of your theme. If the theme is off the shelf then it likely won’t support thumbnail images for attachments because — as you have experienced — attachments do not normally appear in search results.

This is because in a normal theme each result will use the the_post_thumbnail() function to display the thumbnail. Under the hood the featured image itself is an attachment-type post. This function gets the ID of the post’s featured image and uses that ID in wp_get_attachment_image(), which outputs the image/thumbnail for an attachment.

Since attachment posts don’t have a featured image, since they are already attachments themselves, this function won’t display anything.

Therefore to display the image for an attachment post the template would need to check if the post is an attachment, and if so skip the_post_thumbnail() and go directly to wp_get_attachment_image() with the post’s own ID. You can see from this example that this is how the attachment template displays the image.

In practice this would look something like:

if ( get_post_type() === 'attachment' ) {
    echo wp_get_attachment_image( get_the_ID(), 'large' );
} else {
    the_post_thumbnail( 'large' );
}

The exact image size to use in place of 'large' depends on what your theme already uses.

This would involve modifying your theme files, and the exact file depends on the original theme. You will need to check your theme files against the Template Hierarchy to see which files are actually being used. Whichever file it is, you should make your changes by creating a Child Theme. This will ensure the change is safe from updates to your theme, which would normally erase any changes.

Another method that won’t involve modifying templates (but will still require you create a child theme or custom plugin to put the code in) would be to filter the request for the post thumbnail ID.

Deep down the_post_thumbnail() uses get_post_meta( $post->ID, '_thumbnail_id', true ); to get the ID of the attachment that is the featured image for the post. You could filter this so that if WordPress is requesting that meta value for a post, and the post is an attachment, return the attachment’s ID instead.

You can do this with the get_post_metadata filter:

function wpse_300128_attachment_post_thumbnail( $value, $post_id, $meta_key, $single ) {
    if ( get_post_type( $post_id ) === 'attachment' && $meta_key === '_thumbnail_id' ) {
        return $single ? $post_id : array( $post_id );
    }
}
add_filter( 'get_post_metadata', 'wpse_300128_attachment_post_thumbnail', 10, 4 );

With that filter active, any time WordPress tries to get the thumbnail ID of an attachment post, it will receive the ID instead. The return value is either just the ID or an array containing the ID based on the value of $single. This is so that the result will be the expected format regardless of whether the original call has $single set to true or false.

Leave a Comment