The Day I Tried to Update Nelio External Featured Image

Published in WordPress.

As you may already know, you can only set the featured image of your posts using the images available in the Media Library. In May 2014 we published a simple, yet very powerful plugin to overcome this limitation: Nelio External Featured Image (NelioEFI for short). With NelioEFI, you can use any image in the world wide web and set it as your post’s featured image. Since we first released NelioEFI, the plugin has been downloaded over 18,000 times and it’s currently active in more than 5,000 WordPress installations.

A few weeks ago, I released a new version of the plugin to improve its compatibility with certain themes, but things didn’t work out as expected. Today, I’ll help you to understand how the plugin works, why it needed the update, what went wrong, and how we fixed it.

How Featured Images Work

By default, if you want to set the featured image of a post, you can only use one of the images available in the Media Library. As I already said, our plugin tries to overcome this issue and extend the functionality to any image… but before diving into the details of our plugin, I think it’s worth taking a look at how WordPress deals with the images you upload to the Media Library. When a new image is added, this is what happens under the hood:

  1. The image is saved in your media folder. By default, this is wp-content/uploads.
  2. A set of thumbnails is generated. Depending on your theme’s setup, WordPress will generate one or more thumbnails of the recently-uploaded image. These thumbnails are then used by your theme as it needs to. Thus, for instance, a widget of recent posts might include a super-tiny thumbnail (50×50 px), whereas the featured image of a single post page might use the full-size version of the image.
  3. Image meta-information is saved in the database. Finally, WordPress creates two new entries in the wp_posts and wp_postmeta tables.
    1. The former stores the name of the image, the date in which it was uploaded, and so on. The post type used for images is attachment.
    2. The latter is actually two meta entries: _wp_attached_file, which is the relative path to the featured image, and _wp_attachment_metadata, which is an array that contains information about all the available thumbnails generated in step 2.

When you set the featured image of a post, WordPress simply creates a new post meta named _thumbnail_id in that post, pointing to the ID of the image. This ID is, as you can imagine, the ID of the entry WordPress created in step 3.1.

At this point, there’s only one question that needs to be answered: How is the featured image actually printed in the front-end? Note that everything we need is properly set: we have an image in the library, ready to be used by WordPress at any moment, and we linked a post to its featured image using the _thumbnail_id meta.

Themes are responsible of the look and feel of your site. Depending on the theme you use, your WordPress will have one appearance or another. Therefore, your theme is the one who will actually print the featured image of your posts.

There are multiple approaches for printing featured images, but all of them have one thing in common: they rely on WordPress built-in functions. Let’s take a quick review to each of them.

Print the Image Tag Manually

The usual tag for printing images in an HTML document is img. This is how it looks like:

In order to achieve this behavior in WordPress, we simply need to obtain the URL of the featured image and print it inside the src attribute of an img tag:

which generates the same tag we saw before:

Use the URL Anywhere

Once you have the URL of the featured image, it’s easy to use anywhere. For instance, you can use it as the background property of a div tag:

or you can use the image URL in a JavaScript-based gallery. Anything’s possible here!

Let WordPress Print the Tag

In my opinion, the best approach here is to let WordPress print the img tag for you. There’s a function called the_post_thumbnail() that generates the following tag:

As you can see, the new tag has some useful attributes properly initialized (such as the dimensions of the image or an alternative text, as well as a couple of classes).

Our Plugin for External Featured Images

Smile
Girl taking a picture. Image by Cubmundo

As you can see, adding a featured image in a theme is no rocket science. Either you use the useful the_post_thumbnail() function to get the image tag, or you obtain the URL of the featured image and print it wherever you want, however you want.

Nelio External Featured Images extends your posts by adding a new post meta named _nelioefi_url. This meta stores, as its name suggest, the URL of an external featured image.

Once we know the URL of the external image, the plugin has to instruct the theme to use that URL instead of anything else. In order to do that, the plugin hooks into a filter called :

Essentially, the function receives the current HTML image tag and the ID of the post. Our function simply checks if the given post uses an external featured image (uses_nelioefi) and, if it does, it replaces the original HTML tag with a new one (nelioefi_get_html_thumbnail).

(In case you’re wondering, here you have the helper functions that are used for actually printing the featured image.)

The resulting, generated HTML file looks as follows:

which has the following interesting attributes:

  • The image source is a base64-encoded, 1×1 px transparent gif.
  • The actual image is inserted by means of an inline CSS property (note the style attribute).
  • The CSS rules include the size of the featured image (width and height attributes), as well as the cover CSS background size value.

Using this setup, we’re able to scale and crop the featured image, without altering its aspect ratio. Compare the results of the previous approach:

Thumbnail using the cover CSS background size property
Thumbnail using the cover CSS background size property

to the results of this other approach:

Thumbnail with a broken aspect ratio
Thumbnail with a broken aspect ratio

That’s why our plugin does not use the URL of the featured image directly, but uses a transparent GIF and the actual image is inserted in an inline CSS.

However, There’s a Big Problem…

Now, there’s a BIG problem with the approach Nelio External Featured Image uses—it only works if the theme uses the_post_thumbnail for printing the featured image! If it uses any other approach (as the ones we’ve described before), the plugin has no effect. That’s why there are so many tickets (for instance: 1, 2, 3) in which I ask users to send me their theme and look for a solution: I analyze how their theme works and I tell them how to modify their theme so that they use the function our plugin can hook into.

Possible Solution to Overcome the Issue

At this point, I was quite tired of fixing over and over and over again the same problems. Each time a new user downloads the plugin, there’s a chance that her theme is not using the “appropriate” function, which means she’ll need my help to overcome the issue. I’m not saying I was/am not happy to help people, but I couldn’t help but feel that the plugin should be improved somehow. If I wanted to improve our plugin, I had to take a closer look at WordPress‘ source code and determine if there were any actions or filters I could hook into and overwrite the custom external featured image. And so I did!

A closer inspection revealed that there’s only one hook I could use to overwrite the featured image. In wp-includes/media.php, there’s a function (and hook) named image_downsize. This function is the first thing that wp_get_attachment_image_src calls (which, in turn, is called by wp_get_attachment_image or get_the_post_thumbnail), making it the perfect candidate for inserting our own external featured image:

Passing a truthy value to the filter will effectively short-circuitdown-sizing the image, returning that value as output instead.

Documentation of the hook

And this is what I did in versions 1.3.x:

  1. NelioEFI creates a new attachment in your media library. This attachment is just a transparent PNG image that will serve as a placeholder (or frame) for the actual real (external) featured image. Note this placeholder can be properly scaled and cropped by WordPress, as we discussed a few paragraphs above.
  2. When you add an external featured image to one of your posts, the _nelioefi_url meta is initialized with the URL of that image, and the special “placeholder” we created in step 1 is set as the post’s regular featured image.
  3. NelioEFI hooks into the image_downsize filter and replaces the placeholder’s link (for instance, http://example.com/placeholder.jpg) with a new link that contains the URL of the external featured image (such as http://example.com/placeholder.jpg?nelioefi=http://external.com/path/to/image.jpg).
  4. Finally, we simply need to “paint” the placeholder (which, remember, is a transparent PNG image) with the actual featured image. In order to do that, a tiny JavaScript adds an inline CSS to the element that contains the placeholder and sets the featured image as the background of that element (so that it becomes visible).

You can take a look at the source code here.

Unfortunately, this solution caused some additional problems on some installations (during a couple of days there were a lot of new comments in the plugin’s support section). Just to mention a few issues:

  • Social sharing. Social networks such as Facebook or Twitter now add a featured image when sharing a blog‘s content. Using a transparent placeholder and relying on JavaScript for displaying the actual external featured image results in a “broken” image on social networks.
  • JavaScript-based galleries. The same problem applies to some JavaScript-based image galleries. They assume that WordPress returns the URL of the external featured image, but our hook returns the URL of a transparent PNG image with a parameter to the actual featured image… that was not a good idea.
  • Load times. Even though we always return the same placeholder, the extra parameter we added makes each version look different (http://example.com/placeholder.jpg?nelioefi=http://external.com/a.jpg is not the same as http://example.com/placeholder.jpg?nelioefi=http://external.com/b.jpg)… In the end, we have to load an image from the WordPress server each time we use an external featured image, so why don’t we simply upload the external image to our server?

Rollback and The Future of NelioEFI

After all the issues version 1.3.x caused, I decided to roll back to version 1.2.x and work on a better, more stable version. I really think that using the image_downsize filter is the proper way to go (for instance, Photon by Jetpack uses it), but I still need to work on the scale/crop issues.

So, apparently there’s not a one-size-fits-all solution and, therefore, I’ll have to tweak the plugin so that implements different approaches and let each user decide which one works best on her theme. There’s always a lot of work to do! I’ll keep you posted, folks!

Featured image by Clement127.

Leave a Reply

Your email address will not be published. Required fields are marked: •

I have read and agree to the Nelio Software Privacy Policy

Your personal data will be located on SiteGround and will be treated by Nelio Software with the sole purpose of publishing this comment here. The legitimation is carried out through your express consent. Contact us to access, rectify, limit, or delete your data.