Playing with themes, many of them abandoned the timthumb library using directly the “image resize” service of WordPress. This services is not a “on demand” method of resizing (like the one of timthumb, for example), but generates a thumbnail of a given image and return back the URL of that image.

The problem with this method is that it saves the new thumbnail inside the original image folder.

Now, a theme needs thumbnails in very different sizes. For the slider, for the post list widget, for the post list on category and tag pages, for the featured posts on the home page. Using the image resize service of WordPress we ends with an uploads folder which grows and grows of not useful image versions.

While the original uploaded image and some of the predefined WordPress thumbnail must be saved on that folder (since they are directly referenced from the post content), other versions which are created when needed should be stored in a separate folder (a cache) which can be deleted or at least excluded from backup!

If I need to refresh the thumbnails for any reason, I should be able to delete the cache and the system will regenerate them. Or if I change the theme with a new one which uses other thumbnail sizes, I should be able to remove the ones created by the old theme (which are no more useful).

Good, so what can we do with the minimum effort possible? Here a function every theme or plugin can include (renaming it!): with few lines of code and still using the image resize service of WordPress, the new thumbnail is stored inside the /wp-content/cache/thumbnails folder.

The function does a file modification check and regenerates the thumbnail if needed. If you delete the cache not worries, thumbnails will be regenerated when needed.

More, this function extract the first image associated to the post if not a featured images is available. There are too much themes which fail on that point. Old blog with lot of posts without a selected feature image cannot use them!

I have not considered the case of old WordPress version without theĀ get_post_thumbnail_id() function.

Note that the returned thumbnail’s URL has a query string appended to make the the URL unique in case of regeneration. You can remove it if you prefer since the best practices want the static resource without query string because “in the middle” proxies may not cache them.

Contributions are welcome.

function get_post_thumbnail_url($post_id, $width, $height, $crop = true) {
        $image_id = get_post_thumbnail_id($post_id);
        if (empty($image_id)) {
            $attachment = get_posts(array('numberposts' => 1, 'post_parent' => $post_id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order id'));
            if (empty($attachment))
                return;
            $image_id = $attachment[0]->ID;
        }

        // Relative file name to the uploads dir
        $file = get_post_meta($image_id, '_wp_attached_file', true);
        $dot_extension = '.' . pathinfo($file, PATHINFO_EXTENSION);
        $name = wp_basename($file, $dot_extension);
        $dir = dirname($file);

        $uploads = wp_upload_dir();
        $absolute_file = $uploads['basedir'] . '/' . $file;

        $thumbnail = $dir . '/' . $name . '-' . $width . 'x' . $height . $dot_extension;
        $absolute_thumbnail = WP_CONTENT_DIR . '/cache/thumbnails/' . $thumbnail;
        if (!file_exists($absolute_thumbnail) || filemtime($absolute_thumbnail) < filemtime($absolute_file)) {
            wp_mkdir_p(WP_CONTENT_DIR . '/cache/thumbnails/' . $dir);
            $r = image_resize($absolute_file, $width, $height, $crop, $width . 'x' . $height, WP_CONTENT_DIR . '/cache/thumbnails/' . $dir, 90);
            if (is_wp_error($r)) {
                return '';
            }
        }

        return WP_CONTENT_URL . '/cache/thumbnails/' . $thumbnail . '?' . @filemtime($absolute_thumbnail);
    }

Similar Posts

One Comment

Leave a Reply