Adding overlays to images with dynamic URLs

How to allow Image Source Control to identify images with manipulated URLs.

In a recent support case, the customer’s agency used a script to automatically crop images from the Media Library and deliver them with new URLs in the frontend. This prevented Image Source Control from matching these image URLs with the appropriate entries in the Media Library to display the image caption.

Since this was not the first case, I documented the solution for similar causes. I hope other developers will benefit from it.

This post helps you to

  • Analyze if the image URLs in your post content and database are matching,
  • Analyze the cause of image URL mismatches,
  • Matching image URLs with image post meta using the image ID in the frontend or a filter to change the URL dynamically.

Mismatch of image URL and Media Library data

When uploading an image into the Media Library, WordPress stores it and various resized versions on your server under wp-content/uploads/.

Depending on your settings, it might store them in subfolders with the year and months, e.g., wp-content/uploads/2025/01/.

This path is also stored in the _wp_attached_file post meta value in the wp_postmeta table.

So, if I upload an image with the filename mismatch-image-url.png into the Media Library, it would be stored under the path

/wp-content/uploads/2025/01/mismatch-image-url.png

on the server. The path stored in _wp_attached_file would be

2025/01/mismatch-image-url.png

Depending on the media settings in your WordPress installation, there would also be resized versions on the server.

In the frontend, the image – especially if used within the post content – is displayed using an IMG HTML tag, including all resized versions.

Here is an example from my local test site.

<img decoding="async" width="1024" height="585"
  src="http://isc.dev/wp-content/uploads/2025/01/mismatch-image-url-1024x585.png"
  srcset="http://isc.dev/wp-content/uploads/2025/01/mismatch-image-url-1024x585.png 1024w,
    http://isc.dev/wp-content/uploads/2025/01/mismatch-image-url-300x171.png 300w,
    http://isc.dev/wp-content/uploads/2025/01/mismatch-image-url-768x439.png 768w,
    http://isc.dev/wp-content/uploads/2025/01/mismatch-image-url-1536x878.png 1536w,
    http://isc.dev/wp-content/uploads/2025/01/mismatch-image-url.png 1792w"
  sizes="(max-width: 1024px) 100vw, 1024px">Code language: HTML, XML (xml)

When Image Source Control now looks for the proper image caption, it takes the URL of the main image and looks it up in the database. That works very reliably on a standard WordPress installation.

Manipulating the image URL

In this case, the agency uses the Timber framework to build their client’s WordPress theme. This framework includes a resize feature for images, which manipulates the image URLs used in the frontend.

The original URL

2025/01/mismatch-image-url.pngCode language: plaintext (plaintext)

would become something like

2025/01/mismatch-image-url-250x250-c-default.pngCode language: plaintext (plaintext)

However, the post meta entry _wp_attached_file would stay unchanged.

This prevents Image Source Control from matching the image file in the frontend with author attributions to show the image caption or index the image for the global image sources list.

There are two solutions to this.

1. Adding the image ID

Image Source Control only uses the image URL as a fallback method when displaying the image caption. The first attempt is to find the wp-image-ID class, with ID being the attachment ID from the media library.

WordPress automatically adds the image ID class to the IMG tag, so matching still works in many cases of manipulated image URLs. E.g.,

<img class="wp-image-321" … >Code language: JavaScript (javascript)

The Timber framework or agency used a custom image HTML format, so the ID was missing. The client could add it to the code template to allow Image Source Control to identify the image quickly.

2. Filter the image URL

If adding the image ID isn’t possible, one can use the isc_filter_url_pre_get_image_by_url filter hook to manipulate the image URL when Image Source Control tries to find it in the database.

So in the case of

2025/01/mismatch-image-url-250x250-c-default.pngCode language: plaintext (plaintext)

the filter can be used to change the path back into

2025/01/mismatch-image-url.png

before trying to find a matching _wp_attached_file entry in the database.

The following code performs the change:

/**
 * Filter to transform Timber resized image URLs back to their original form
 * https://github.com/timber/timber/blob/1.x/lib/Image/Operation/Resize.php::filename()
 * 
 * @param string $url The image URL to transform
 * @return string The original image URL
 */
add_filter('isc_filter_url_pre_get_image_by_url', function( $url ) {
    if ( empty( $url ) ) {
        return $url;
    }

    // Check if the URL contains the resize pattern
    if ( strpos( $url, '-c-' ) === false ) {
        return $url;
    }

    return preg_replace( '/-\d+x\d+-c-\w+(?=\.\w+$)/', '', $url );
});Code language: PHP (php)

I won’t go into the specifics here, but I will tell you how I quickly found the solution: I asked ChatGPT. I wanted to test whether I could recommend it to my users, and it worked on the first try.

Here are the steps:

  1. I gave ChatGPT the whole code from here.
  2. Then I gave it the following prompt:

I have the following filter in my WordPress plugin and would like to use it to change the URL back to the original. Please write me an appropriate filter function:

$url = apply_filters( ‘isc_filter_url_pre_get_image_by_url’, $url );

3. This resulted in the code above.

Conclusions

This post was overdue. It explains why Image Source Control might not be able to match image URLs and image metadata, where you can find the appropriate information to analyze the problem and two solutions to fix it.

Please let me know if you tried this and how it works.

Portrait of Thomas Maier, founder and CEO of Image Source Control

Questions? Feedback? How can I help?

Reach out directly via the contact form.