Adding Feature Images to WordPress with the Easy Featured Images Plugin

Adding Feature Images to WordPress with the Easy Featured Images Plugin

From the Posts interface in the backend of WordPress it takes fives clicks to add a feature image to a post. I’ve created a new, free plugin, which reduces the number of clicks to just three – and I’m going to walk you through how I built it.

I’m working on a large project at the moment – a website rebuild – and I wanted to create a way to add, modify and delete featured images without having to manually edit each post. I also need to retrospectively add and update images, which can take considerably longer if I have to wait for images to upload.

When I began working on this project I decided that I wouldn’t build plugin functionality into my custom theme. Instead, if something should be a plugin, it would be – and it would be released for free.

The end result is Easy Featured Images, and today I want to walk you through you how it was made, from start to finish.

What We’ll Be Making

The plugin essentially adds a column to the post list. The column displays either the featured image or a prompt to add a featured image. When you click on either one, the WordPress media uploader appears and you are able to select/upload an image.

When you click the “Set featured image” button the image is displayed in the post list and is set as the featured image via AJAX, no reload necessary. The remove link allows you to remove the featured image instantly.

Take a look at this GIF demo for a quick overview:

Easy Featured Images

The plugin is not overly complicated but it does offer a good mix of useful-to-know things you can apply in your own work. Nonces, Ajax, modifying admin lists, how to use the native uploader and more, as well as how to add a plugin to the WordPress Plugin Directory and so on.

Let’s get started!

The Framework

I decided that I wouldn’t use a framework for this plugin. I am a huge fan of the WordPress Plugin Boilerplate, but the PHP in this plugin consists of three functions, so I decided I could manage things myself without too much trouble. Hence the only framework I needed was a plugin folder and the main plugin file. Here’s how I did it:

In a local WordPress installation I went to the wp-content/plugins directory and I created a new folder named easy-featured-images. Within that folder I created the easy-featured-images.php file which is the main plugin file. Inside that file I added a comment, which contains some information about the plugin.

This is used by WordPress to display the plugin in the backend plugin list. Once you’ve saved the file you should see the plugin show up. It will look something like this:

Easy Featured Image Plugin List

Adding a New Post Column

The first thing we want to do is add a new column to display the featured images in. We can use the manage_[POST_TYPE]_posts_columns hook to do so. We need to replace [POST_TYPE] with the slug of the post type we want to add a new column to. For now this will be the blog post screen so we will use post.

Note how the function is documented using the phpDoc standards. In the plugin itself all functions are documented like this. I will omit them in this article from now on.

The first parameter passed to this function is the set of columns already in place. The keys of the array are the slugs of the columns, the values are the names. Normally adding a value is as easy as adding a member to the array. However, this will add it to the end and I wanted to add it in second position.

The first column is used by the checkbox so I split the array in two. The first one contains just the checkbox, the second one contains the rest. I also created a third array with just one member our new image column.

I merged these three arrays – sticking our image field in the middle – creating the final array of columns, the image field in second place. If done right you should see a new column in the post admin without any content.

Adding Content to the Column

Adding content is done by hooking a function to manage_[POST_TYPE]_posts_custom_column. You need to be careful with this function as it will return content for all columns so you need to use if statements to target specific ones.

Before we write the PHP, let’s discuss some HTML. The most important thing to realize is that I didn’t arrive at the final code on my first go. I started out with a simpler structure but realized that I needed more once I got going.

There are three main parts to our HTML. One is the display of the featured image. I wanted to show the small thumbnail and a larger version on hover. If there is no featured image we need a display that prompts users to add one. Finally, we need a remove image link which will remove the featured image when clicked.

The main points here are the following. The element with the efi-thumbnail class also receives no-image if there is no thumbnail attached. The efi-images element contains a prompt to upload an image or two images – the thumbnail and medium sized versions. The medium size version will be hidden, it will show up when you hover over the efi=images element.

We also have a remove image link. This is actually always there. We’ll use CSS to hide it if the main container has the no-image class.

One more thing to note is that since we’ll be working with Javascript there really is no need to use links everywhere, so what gives? Just in case anything goes wrong, these links will take users to the edit post page. This is useful if JS is turned off (quite rare nowadays) or if another plugin causes a Javascript issue which affects our plugin. The final PHP will look like this:

The whole code is wrapped in an if statement which separates the code of our column from all the rest. Use the slug you set in the previous function here. The first parameter of the function is the slug of the column, the second is the id of the post.

I used wp_create_nonce() to add some extra security, and also to be able to use internal WordPress functions later on, I’ll explain when we get to the Javascript. For now the important bit is that a nonces are a layer of security that make sure a user has the permissions and the intent to perform a specific action.

The rest is straightforward, I used get_edit_post_link() to retrieve the link to the post’s edit screen and get_the_post_thumbnail() to grab the thumbnails at different sizes.

I also used Dashicons, the icon font WordPress uses to make the display nicer without having to resort to images or other resources. You can add any available icon in the backend using this format:

Replace icon in the second class with the name of the icon you need. You can look up the names using the link above or the list on Kevin Leary’s website. I prefer the latter because you don’t need to click on the icon first to see the name.

Styling Content

Without a stylesheet our table looks awesome just now. Let’s fix that by enqueueing our styles using the admin_enqueue_scripts hook.

The first parameter allows us to enqueue our assets only on the pages we want. In our case this is the edit page. In all other cases we quickly return before any scripts or styles are added. As you can see we’re linking to a style.css in the plugin directory, create that file now and use the following CSS to make it look like our example.

The first thing I did was limit the width of our column, it really shouldn’t take up too much space. I made it 72px wide – along with the small thumbnail.

The medium size image is positioned absolutely to the top left of the container. When the user hovers over the .efi-images element the medium size attachment is shown, covering the thumbnail.

The add image link has a bunch of rules to make it look nice. I used display: table-cell to be able to align the text vertically without the need for additional container elements. I also added a transition to make the hover experience a bit better. Notice that the transition is removed from the dashicons. Since they have their own transition, this would run in addition to our own which is a bit off-putting.

At this point things should be shaping up nicely. Images are displayed, hover transitions work, the add image link looks nice.

Easy Featured Image Post List

Javascript Functionality

The Javascript side of our code is the most complex so instead of pasting the whole code I’ll work in steps here.

Enqueueing Javascript

We’ll use the same efi_enqueue_assets() function we used for CSS but we need to discuss some things beforehand. I mentioned we’ll be using the built-in WordPress media window to upload/select images. This requires a number of scripts and styles to be added. WordPress has made this easier by providing the wp_enqueue_media() function to do it for us. We’ll need to add it to our enqueue function.

We also need a way to translate some strings in our Javascript file, and also to tell it where our admin-ajax.php file is. This is provided by WordPress as a framework for AJAX calls, it is found in the wp-admin folder. We can pass our translations and the admin ajax URL using the wp_localize_script() function which will also be a part of our enqueue function . Here’s the final version:

The first parameter of wp_localize_script() is the handle of the script we want to localize. The second parameter will be the object name we can use to refer to our strings. The third parameter is the translation array. The keys will be used to refer to the values. For example: we can use efi_strings.browse_images in our Javascript to output the text specified here.


Our best pro WP tools in one bundle

Try free for 7 days
30-day money-back

By wrapping the __() translation function around the text I made sure that users can translate this later.

Media Uploader Framework

I cheated a bit and used the code from Tom McFarin’s Your Own Instance of the WordPress Media Uploader article. Thanks Tom! Here’s a slightly modified version without comments.

The essence is this: When we click the .efi-choose-image element we check if file_frame is defined, this holds an instance of the media uploader. If it exists we use the open() function to display it. If it doesn’t we create it using the function. We pass the title (shown at the top of the window) and the button text.

Using the file_frame.on( 'select', function() {}) section we define what happens when the user clicks on the image and finally we open the newly created file_frame. We also return false at the very end to prevent the link from actually firing and taking the user to the post edit page.

Handling Image Displays

Without further ado, here is the code used in the actual plugin. I’ve defined some more variables and used our translation object when creating file_frame but most of this is the same as before. The meat of this code is inside the select even so let’s look at that in detail below the example.

I created a thumbnail and medium variable to store the data of these image sizes. This includes the width, height and URL of the images. If the post already has a featured image we have two image elements, all we need to do is replace the src properties.

If the post doesn’t have a featured image all we have is the add new link, we need to create these elements. First we remove the no-image class. We them find the add image link and duplicate it. I decided to go for this approach because it already contains a link to the post so we don’t need to pass it using the translation array. The links are now correct, we just need to put an image in them.

Using the thumbnail object’s properties we create an image element with a number of attributes. The classes added are the same as WordPress would add to the image. Finally, the alt property is pulled from the image_data object (which contains the data for both the thumbnail and the medium sized image) because the alt text is common to all image sizes.

We do the same for the medium size image and place them within the links. We then wrap the whole thing inside the efi-images element to end up with our final HTML structure.

At this point uploading/selecting images will work just fine. The images will not be saved to the post so if you reload the page you will end up where you started but we’re almost there.

Assigning the Featured Images

This part consists of only a couple of lines but the explanation is a bit complex. However, I think it is important to understand how I got there. The selected image needs to be displayed in the post list and it needs to be actually added to the post as a featured image – this is where AJAX comes in. We could write our own handler for this. We know that featured images are stored in the post meta table using the _thumbnail_id key, it would be a matter of using update_post_meta() with the correct parameters. However, why not use the same mechanism WordPress uses?

I went to the post edit page and added a featured image. I used Chrome Developer Tools to figure out how WordPress adds the featured image. We have a post here at WPMU DEV about using Chrome Developer Tools for things like this, take a look for more info. The header of the request made by WordPress looks like this:

Featured Image Request

This means that if we use the correct parameters we won’t even need to write a function to make this work, we’ll be using WordPress’ native one! The only challenge is the nonce. When creating a nonce we need to know the name of the action used. I dug around a but in the source code until I found the core code responsible for creating the nonce for the featured image, the nonce action name is set_post_thumbnail-[PostID]. This is where the code for creating our nonce comes from!

So, to add a featured image using WordPress’ built-in function we need to use AJAX to post some data to the admin-ajax.php. The data must contain the nonce, the post id, the thumbnail id and the action set-post-thumbnail.

Removing Featured Images

The same mechanism applies here. We need to make sure that visually it all works and we also need to use AJAX to actually remove the image in the database. The following code should be added to our Javascript file after the on click function.

We figure out the nonce, url, post_id and add the no-image to the parent element. We then create a choose image link by building the same HTML structure as in our PHP file. We replace the contents of .efi-images with our newly formed link.

Finally, we use WordPress’ built-in function for removing the featured image. The format is exactly the same as you saw before. The only difference is that the thumbnail id needs to be set to -1.

Adding the Plugin to the Repository

Adding a plugin is actually pretty easy. Here are the basic steps, I’ll go through how I did each one below:

  • Create a plugin readme file
  • Zip it all up and submit it to the directory
  • Once approved, add your files to the SVN system
  • Create optional assets for better display

Creating a Plugin Readme File

This one isn’t too difficult because not only does WordPress have an excellent readme template but a readme validator as well. Here’s the plugin’s readme in its entirety:

Note that it doesn’t have three sections which are sometimes found in other plugins. You can add an upgrade notice section if anything special needs to be done during an update. A FAQ section is also available but since this is a first version I don’t have frequent questions just yet. Finally, a donate link is also available which will be displayed on the WordPress plugin page.

Zip and Submit

Once you have your readme file in the plugin folder, zip it all up and submit it. Be aware that the plugin name you enter here will translate to the URL directly, which will also be the name of the project in the SVN repository. I chose Easy Featured Images because the URL will be easy-featured-images.

Make sure to add a few notes to the nice people reviewing your work. They get tons of submissions every day and a thank you at the end should be the minimal amount of courtesy you show toward them.

Add Plugin to SVN

Once approved you will get access to an SVN repository. This takes anywhere between 24-72 hours, and depending on how complex your plugin is it may take longer. You should get an email containing the details and some helpful links, something along these lines:

Plugin Acceptance

SVN is a version control system WordPress uses, you need to add your plugin to it for it to show up in the repository. If you want to learn more about SVN I suggest looking at the WordPress documentation or, even better, the free SVN Book available online.

To use SVN you’ll need the terminal or an app like Tortoise SVN for Windows or SVNx for Mac. I use the terminal since it seems to be the fastest.

I go into any directory I like and type svn co This checks out the plugin into the directory. The new folder contains four sub-folders: assets, trunk, branches and tags. The trunk folder should contain the development or most recent version of the plugin. I copy all files from the plugin directory in there.

I then type svn add * to add all the new files followed by svn ci -m "Commit Message". I use the commit message to describe the changes I made. This will send the code to the WordPress servers, the plugin will show up after 15-20 minutes if you search for it online.

Optional Assets

If you want to make your plugin look great and add some screenshots in the process you’ll need to use the assets section. I added three images: two for the plugin icon and one for the large banner. The banner should be 772px x 250px, and should be named banner=772x250.png.

It will show up on the plugin’s page in the WordPress plugins section like this:

Plugin Banner

You can also add a 256×256 and a 128×128 icon to the assets. These show up in the plugin finder within the WordPress admin. They add a much needed splash of color and uniqueness to your plugins, I really recommend creating these files. The files need to be named icon-128x128.png and icon-256x256.png respectively. Once added they will show up in the plugins section like this.

EFI plugins view


There you have it, a complete plugin which does something useful from zero to publishing in the repository. If you need this functionality and have some time I urge you to try and build it for yourself – it will help you grow as a plugin developer.

If you don’t have the time you can grab the actual plugin, Easy Featured Images, from the WordPress Plugin Directory. Have a great time developing your own stuff!

Do you have any tips for building plugins and uploading to the WordPress Plugin Directory? Tell us in the comments below.

Daniel Pataki

Daniel Pataki Daniel is the CTO at Kinsta and has written for many outstanding publications like WPMU DEV and Smashing Magazine. In his spare time, you'll find him playing board games or planning the next amazing office game like the not-at-all-destructive Megaball.