Cyber Monday Sale 40% off unlimited courses & creative assets! 40% off unlimited assets! Save Now
  1. Code
  2. Plugins

How to Create a WordPress Avatar Management Plugin: Finishing Touches

Read Time:26 minsLanguages:
This post is part of a series called How to Create a WordPress Avatar Management Plugin from Scratch.
How to Create a WordPress Avatar Management Plugin from Scratch: Getting Started

Avatar Manager for WordPress is a sweet and simple plugin for storing avatars locally and more. Easily.

Enhance your WordPress website by letting your users choose between using Gravatar or a self-hosted avatar image right from their profile screen. Improved workflow, on-demand image generation and custom user permissions under a native interface. Say hello to the Avatar Manager plugin.

A Quick Recap

In the first part of our tutorial, we reviewed:

  • what is a WordPress plugin;
  • how to create a basic WordPress plugin, choose an appropriate license and format for the version number;
  • what are action and filter hooks and how to use them to create our plugin;
  • how to add new settings to existing settings screens;
  • how to make a plugin more flexible by using custom options.

Today, we'll take things further and wrap up our plugin: we'll handle avatar uploads and on-demand image generation, internationalize our plugin and much more.

Step 1. Resizing an Avatar Image

Let's start by writing the following function:


  • The avatar_manager_avatar_resize() function generates a resized copy of the specified avatar image.
  • The wp_upload_dir() call returns an array containing path information on the currently configured uploads directory.
  • The str_replace() function replaces all occurrences of the search string with the replacement string.
  • The pathinfo() function returns information about a file path.
  • The wp_basename() function is the i18n friendly version of basename() which returns the trailing name component of a path.
  • The file_exists() function checks whether a file or directory exists.
  • The skip flag is set to true if the destination image file already exists, else a new image is generated.
  • The wp_get_image_editor() function returns a WP_Image_Editor instance and loads a file into it. With that we can manipulate the image by calling methods on it.
  • The is_wp_error() function checks whether the passed variable is a WordPress error.
  • Then, we resize and save the image by calling the resize() and save() methods of the $image object.
  • The do_action() executes a hook created by add_action(); this allows themes and plugins to hook to the avatar_manager_avatar_resize action which is triggered after resizing an avatar image.

Step 2. Deleting an Avatar Image

Before taking care of profile updates, we need to define one more function:


  • The delete_attachment action hook is called when an attachment is deleted by wp_delete_attachment().
  • The get_post_meta() returns the values of the custom fields with the specified key from the specified post. First, we test if the attachment with the specified ID is an avatar image.
  • The is_array() call finds whether a variable is an array.
  • Then, we use the unlink() function to delete the avatar image including its resized copies, but skipping those with the skip flag set to true.
  • The delete_post_meta() function deletes all custom fields with the specified key from the specified post.
  • The get_users() function retrieves an array of users matching the criteria given in $args.
  • The delete_user_meta() function removes metadata matching criteria from a user.
  • Lastly, we execute the avatar_manager_delete_avatar action hook.

Step 3. Updating a User Profile

When updating a user profile, we need not only to save the options changed by the user but to handle avatar uploads and removals too. Let's do it:


Handling Avatar Uploads

To handle avatar uploads, write the following code:


  • The function_exists() returns true if the given function has been defined, then the require_once() statement checks if the specified file has already been included, and if so, doesn't include it again.
  • The wp_handle_upload() function handles PHP uploads in WordPress, sanitizing file names, checking extensions for mime type, and moving the file to the appropriate directory within the uploads directory.
  • Before adding the new avatar image, we call the avatar_manager_delete_avatar() function to delete the old avatar, if any is set.
  • The wp_insert_attachment() function inserts an attachment into the media library.
  • The wp_generate_attachment_metadata() function generates metadata for an image attachment; it also creates a thumbnail and other intermediate sizes of the image attachment based on the sizes defined on the Settings Media Screen.
  • The wp_update_attachment_metadata() function updates metadata for an attachment.
  • Next, we call the avatar_manager_avatar_resize() function to generate a copy of the avatar image at default size.
  • Lastly, we update the metadata for the attachment and for the user currently being edited.

Removing an Avatar Image

Now, it's time to make the plugin to actually delete an avatar image when requested:


  • If the value of the requested action is remove-avatar we call the avatar_manager_delete_avatar() to delete the specified avatar image.
  • The get_edit_user_link() function gets the link to the users edit profile page in the WordPress admin.
  • The urlencode() function encodes a string to be used in a query part of a URL.
  • At the end of the function, we call the wp_redirect() function to redirect the user back to the updated user profile.
  • The exit call terminates the execution of the script; it's a language construct and it can be called without parentheses if no status is passed.

Step 4. Retrieving a Custom Avatar Image

Next, we're going to write a helper function for retrieving a custom avatar image:


  • The avatar_manager_get_custom_avatar function returns a custom avatar image based on user ID or false if showing avatars is not enabled. The function retrieves plugin options, sanitizes the $size parameter and escapes HTML attributes from $alt variable.
  • Then, it retrieves a default image to use instead of the avatar image if the avatar rating doesn't match. A resized copy of the avatar image is generated on-demand if the requested size doesn't match an existing image file.
  • The get_userdata() function returns a WP_User object with the information pertaining to the user whose ID is passed to it.
  • The md5() function returns the MD5 hash for the provided string.
  • The strtolower() function returns the provided string but with all alphabetic characters converted to lowercase.
  • The is_ssl() call checks if SSL is being used.
  • The sprintf() function returns a formatted string.
  • The hexdec() function returns the decimal equivalent of the specified hexadecimal number.
  • The call strpos() finds the numeric position of the first occurrence of needle in the haystack string.
  • The wp_get_attachment_image_src() function returns an array with the image attributes url, width and height, of an image attachment file.
  • Lastly, we use the apply_filters() function to call the functions added to the avatar_manager_get_custom_avatar filter hook.

Step 5. Retrieving an Avatar Image

Basically, the next function is the main function of our plugin:


  • The avatar_manager_get_avatar() function returns the avatar for a user who provided a user ID or email address, or false if showing avatars is not enabled.
  • We use the get_avatar filter to change the output of the get_avatar() function. Our function retrieves plugin options, sanitizes the $size parameter and finds the ID of the specified user.
  • Then, it returns the result of the avatar_manager_get_custom_avatar() function call, or the unmodified output of the get_avatar() if the user doesn't use a custom avatar.
  • The is_object() call finds whether a variable is an object.
  • The email_exists() function checks whether or not a given email address has already been registered to a username, and returns that users ID, or false if none exists.

To test the result, go to the Users -> Your Profile Screen.

The Avatar Manager plugin options under the User Your Profile ScreenThe Avatar Manager plugin options under the User Your Profile ScreenThe Avatar Manager plugin options under the User Your Profile Screen
The Avatar Manager plugin options under the User Your Profile Screen

Browse for an image an upload it. Now, you should be able to choose between using Gravatar or the custom avatar image you just uploaded.

Step 6. Removing Unnecessary Filter Hooks

If you go to the Settings Discussion Screen you'll notice that the avatars from the Default Avatar setting are replaced with your custom avatar. To fix this issue, we'll restore the default avatars by removing our custom function when it isn't needed with the help of the avatar_defaults filter hook. To do so, add the following code:

To prevent custom avatars from being applied to the Default Avatar setting, we call the remove_filter() function. It removes a function attached to a specified filter hook. This method can be used to remove default functions attached to a specific filter hook and possibly replace them with a substitute.

Step 7. Displaying Custom Media States

The Media Library Screen allows you to edit, view, and delete images, video, recordings, and files previously uploaded to your blog. To identify an attachment being used as an avatar image, we're going to display a custom media state for it:

The display_media_states filter is used to display custom media states for attachmets that have been added to the Media Library. We use the $post global variable to grab the ID of the current attachment. If the _avatar_manager_is_custom_avatar custom field isn't empty, the attachment is an avatar image so we add a custom media state for it.

If you don't have any custom avatar image set up, upload one and go to the Media Library Screen.

The Avatar Manager plugin media states under the Media Library ScreenThe Avatar Manager plugin media states under the Media Library ScreenThe Avatar Manager plugin media states under the Media Library Screen
The Avatar Manager plugin media states under the Media Library Screen

Notice that each attachment being used as a custom avatar image does have the Avatar Image string appended next to its filename.

Step 8. Adding the Uninstaller

In order to handle the uninstall process, a plugin should create a file named uninstall.php in the base plugin directory rather than using register_uninstall_hook(). This file will be called, if it exists, during the uninstall process bypassing the uninstall hook. To do so, open avatar-manager/uninstall.php and add the following code:

When using uninstall.php the plugin should always check for the WP_UNINSTALL_PLUGIN constant, before executing. The WP_UNINSTALL_PLUGIN constant is defined by WordPress at runtime during a plugin uninstall and it will not be present if uninstall.php is requested directly. The defined() checks whether a given named constant exists. The include_once statement includes and evaluates the specified file during the execution of the script; if the code from a file has already been included, it will not be included again. The delete_option() function removes a named option from the options database table.

Step 9. Internationalizing and Translating the Plugin

Once you have the programming for your plugin done, another consideration is internationalization. Internationalization, often abbreviated as i18n, is the process of setting up software so that it can be localized; localization, or l10n, is the process of translating text displayed by the software into different languages. WordPress uses the gettext libraries and tools for i18n.

It is highly recommended that you internationalize your plugin, so that users from different countries can localize it.

Translatable Strings

In order to make a string translatable, you have to just wrap the original string in a __() function call. If your code should echo the string to the browser, use the _e() function instead. As you might have noticed, we've already done that in our plugin.

Text Domains

A text domain is a unique identifier, which makes sure WordPress can distinguish between all loaded translations. Using the basename of your plugin is always a good choice. You can load the plugin's translated strings by calling the load_plugin_textdomain() function, which we've already done in the first part of our tutorial.

PO Files

Now, we need to make a .po file for translators. To do this, we'll use the Poedit translation software. Once you've downloaded it, click File -> New Catalog... to setup a new catalog. A new window should open up. Go to the Project info tab and enter Avatar Manager as the project name.

Poedits Project info tab under the Settings windowPoedits Project info tab under the Settings windowPoedits Project info tab under the Settings window
Poedit's Project info tab under the Settings window

On the Paths tab, let’s leave the base path as . which refers to the directory in which the catalog is.

Poedits Paths tab under the Settings windowPoedits Paths tab under the Settings windowPoedits Paths tab under the Settings window
Poedit's Paths tab under the Settings window

Next, go to the Keywords tab. Remove all the items there, and add in these keywords: __, _e, _n and _x.

Poedits Keywords tab under the Settings windowPoedits Keywords tab under the Settings windowPoedits Keywords tab under the Settings window
Poedit's Keywords tab under the Settings window

Press OK and save the file as avatar-manager/languages/avatar-manager-default.po. Now, the file is ready for translation.

Poedits main windowPoedits main windowPoedits main window
Poedit's main window

Translate all the strings you want and then save the file as avatar-manager/languages/avatar-manager-{locale}.po. The locale is the language code and/or country code you defined in the constant WPLANG in the file wp-config.php.

MO Files

A .mo file is a binary file which contains all the original strings and their translations in a format suitable for fast translation extraction. The conversion is done automatically if you go to Edit -> Preferences -> Editor and check Automatically compile .mo file on save.

Step 10. Releasing and Promoting a Plugin

This section goes through the steps for taking a plugin that you've created and getting it distributed widely.

Submitting to the WordPress Plugin Directory

The fastest, easiest and best way to get your plugin out there is to upload your plugin to the WordPress Plugin Directory. For more details about submitting your plugin see the about page or skip straight to the plugin submission page.

Promoting and Documenting Your Plugin

To submit and promote your plugin to the WordPress Community, first create a page for the plugin on your site with complete and well written instructions. Include a link to this explanation page in the plugin's header, so people can easily check for updates and more information and help.

If you choose to submit your plugin to the WordPress Plugin Directory, also make this information as clear as possible so they can categorize and help others understand the usage of your plugin. You also need to create a readme.txt file in a standard format, and include it with your plugin.


This closes our tutorial; now, we have a fully working plugin and learned some practical tips and tricks about WordPress plugin development. The idea behind this plugin started as a feature requested in WordPress core; I would love to hear your thoughts about it. Does it improve the current workflow? Would you find a similar approach useful but on managing Gravatar images right from your profile screen?

As a bonus, the Avatar Manager plugin is also available on WordPress Plugin Directory and GitHub. Check it out to stay up-to-date with the latest releases. Thanks for reading!


  • WordPress Coding Standards - General information about coding standards for WordPress development.
  • Writing a Plugin - Best starting place for learning about how to develop WordPress plugins.
  • Plugin API - Description of how to use action and filter hooks in your WordPress plugin, and core functions that plugins can override.
  • Function Reference - An article with many of the core WordPress functions useful to plugin and theme developers; lists most of the core functions, excluding Template Tags.
  • I18n for WordPress Developers - Internationalization, including a section on how to internationalize your plugin.
  • Plugin Submission and Promotion - Once you have written your plugin, here are some hints on distributing it widely.

External Links

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.