This tutorial goes through the process of setting up a custom image field for user profiles, disabling Gravatar, and replacing it with local avatars using the ACF field we created. We’ll also include a fallback image for users that don’t upload one.
Let’s face it, even though Gravatar is a really great idea, sometimes it’s not that great. First of all, it can be quite a cumbersome task getting your website users to set up a Gravatar account. Secondly, Gravatar can slow your site down. Think about it. Every time your site needs to display an avatar it needs to check whether that person has a gravatar account, and if it does it needs to grab the image from their (often quite slow) server.
What are the other options?
You can use one of the available plugins to cache your avatars. Great, more plugins with more settings *sarcasm*. These may work fine, but it seems like a lot of hassle.
Another option is to use local avatars. ‘Local’ in this case means local to your website. In other words, not using a 3rd party service for your avatars.
The Easy Solution
Simple Local Avatars is a really cool plugin from the crew at 10up. This plugin creates a custom field on your user profile that allows you to upload an image. It also gives you the option to disable Gravatar altogether.
So what’s the catch?
Actually, there isn’t one. It’s a great plugin. Sometimes you just want more control. I’m already a big fan of Advanced Custom Fields. On many occasions, i’m already using ACF to add custom fields to User Profiles.
The Custom (and still kinda easy) Solution
Recently, I’ve started to play with acf_form() to allow editing (and posting) of new content, including front end editing of user profiles. Awesome. But that’s a post to come at a later date. EDIT: It’s here! Front-end posting and editing.
1: Create a new field group with an Image field in ACF
So, to start… let’s create a new field group if you haven’t already. Then add an Image upload field in ACF and attach it to our user profiles. I’m using ACF Pro (v5) at this point. I’m not sure (probably not) if it’s possible to create custom profile fields with the free version.
I have the field set with a return value of ‘Image Array’. This is just personal preference since I’ll be using this image in other areas of my custom theme as well.
2: Set the field group location
Set the field group location so our new metabox shows up on our User Profile. So, show this field group if User Form | is equal to | Add/Edit.
3: The Code
The next thing we need to do is filter get_avatar to do our magic.
The get_avatar filter is a little tricky, since it needs to get a user by id_or_email. We need to account for both, so the $user line does all of the logic for that. The $image_id line is pulling in our local avatar image. The first $avatar_url line sets our default/fallback avatar for users that don’t upload one. The ‘if’ conditional gets our avatar in a specific size, currently set to pull in the thumbnail. The ending code outputs everything.
4: Our field in action
In your comments, and anywhere else avatars are used in WordPress, you will now see your local avatars including the default fallback avatar set in our get_avatar filter.
Let me know how it works for you!
Dorian Speed says
Excellent writeup! I’m going to use this TODAY. BOOM.
I think Gravatars are especially confusing/cumbersome for non-bloggers who are used to being able to upload a profile photo on Facebook, etc., easily without leaving the site. I have used a different plugin (can’t remember which one) but now that I have been introduced to the glorious world of ACF I shall implement your approach.
JiveDig says
Great! The only other way I would accomplish this is using the other plugin I linked to in the post… Simple Local Avatars from 10up. It that’s ALL you need to do, SLA is probably a better solution. But, if you’re already using ACF for other stuff, it’s a no brainer!
Paal Joachim Romdahl says
I am thinking that there is likely code one can add as a snippet to the functions file or a custom functions plugin that adds a local avatar similar to https://wordpress.org/support/plugin/avatar-manager. I just have not found that code yet. Another approach would be then adding it like your doing in the tutorial.
JiveDig says
Paal, you mean code that doesn’t rely on ACF? There certainly is. I just use ACF most of the time anyway, so it’s easy to just pop this code in.
Bill E. has some code to do it without a plugin http://www.billerickson.net/code/custom-avatar-field/, I just find ACF a clean and pretty way to do it.
Rangel R Morais says
Hi! Thanks for this tuto, but, im trying to make this work on bbPress avatars, i thought i could REPLACE the gravatar with my ACF Pro avatar, then when bbPress searches for the default gravatar, he would show me the ACF instead of Gravatar.
Rangel R Morais says
Hi again! It work pretty well bro! I just forgot to check ” Use avatars” on my wordpress configurations! Thanks A LOT, i ‘ll link this post on my stackoverflow question.
JiveDig says
Great Rangel! Glad you got it. I haven’t tried this code with bbPress, thanks for the confirmation that it works!
Theo says
If it was okay for me to swear, I would – this snippet of code is f**king awesome. Love it – thank you!
JiveDig says
Glad you like it! I knew this one would get re-used quite a but, so I spent some time getting it right. Thanks for checking it out 😉
Andrew Blackwell says
I have to agree. Excellent work. Thank you
JiveDig says
Rock on!
Hugo Arturo says
hola y en dond pegan el codigo disuclpaa
Theo says
Hiya
I just noticed an error comes up when a user makes a comment. When I removed the code, the error disappears so isolated it to the script. The error message is:
Warning: trim() expects parameter 1 to be string, object given in /home/mysite/public_html/wp-includes/capabilities.php on line 567
Can you help please?
Bruno Margenats says
I think I got it.
Just change
$user = is_numeric($id_or_email) ? get_user_by('id', $id_or_email) : get_user_by('email', $id_or_email);
with this:$user = false;
if ( is_numeric( $id_or_email ) ) {
$id = (int) $id_or_email;
$user = get_user_by( 'id' , $id );
} elseif ( is_object( $id_or_email ) ) {
if ( ! empty( $id_or_email->user_id ) ) {
$id = (int) $id_or_email->user_id;
$user = get_user_by( 'id' , $id );
}
} else {
$user = get_user_by( 'email', $id_or_email );
}
I don’t know if this is solution is the better, but it seems to work form me 🙂
Source of the code: https://codex.wordpress.org/Plugin_API/Filter_Reference/get_avatar
Bruno Margenats says
*the best solution
JiveDig says
Hey Theo & Bruno, I apologize for missing your original comment. I’ve since updated my code a bit once I finally got an error as well… but I forgot to update the Gist here.
I just updated the Gist with my current code, which looks to be the same as Bruno’s suggestion on quick glance.
Thanks!
justmecrea says
this demo looks good and i tried it, that’s work fine
but,…
what about front-end ?
tanks VERY MUCH for your BEST EFFORTS
JiveDig says
This function uses a local image for the avatar. Anything that uses the avatar on your site (front end) will now use this image.
deepak says
hi , it works great, but in element or pro dynamic content , I used user profile , but it doesn’t show up there.
Davide says
I have this error in the backend, precisely on the dashboard page of the main widget reviews Woocommerce.
Notice: Trying to get property of non-object in C:\Program Files (x86)\Ampps\www\formazione\wp-content\themes\formazionepoint\inc\extras.php on line 35
In addition to appearing the error message, it is not shown correctly Avatar user, but the default. You know how to solve? In the front end it works beautifully 🙂
Davide says
The problem appears here:
// Get the user id
$user_id = $user->ID;
JiveDig says
in your extras.php line 35, is that the $user_id = $user->ID; line?
You may need to dig into Woo and see how they are calling get_avatar(). I don’t have any guesses at the problem without diving in to try to re-create. Let us know if you find anything 😉
Davide says
Unfortunately they are very skilled in PHP to do it alone. Could you help me pay you the trouble?
Andy says
Thank you, really useful. I needed to use ACF, I couldn’t use one of the various plugins available, and this code snippet worked great for me. Cheers.
JiveDig says
Hey Andy, glad it helped!
Robert Andrews says
What if I want my avatars to be not uploaded but to be remotely hosted?
I have many, many users. They all have a custom field called “photo_url” in the wp_usermeta table – a string of text, full URL, that is a remotely-hosted image (except those users who have none).
How can I disable Gravatar and replace it with *that* ^?
Thanks
JiveDig says
I think we dealt with this via twitter, but for other readers: The above snippet has the image saved by ID. You need to change the code to use the image as a URL, in this case an external URL. The final working code is here. You may want to consider some extra escaping, especially on the url. esc_url($image_url).
Robert Andrews says
FYI, Mike’s reply on Twitter was appreciated, and this works for me.
Daniel Bishop says
Any chance you know how to add support for ‘Guest Authors’ (Co-Authors Plus)?
JiveDig says
Doesn’t Co-Authors Plus just use avatars the normal WP way? If so, this code should work there as well. Are you finding conflict?
Jerod Hammerstein says
This is great. Thank you for posting this. I like being able to use ACF for this.
JiveDig says
Glad you liked it. I’ve used this one many times on projects already using ACF!
Charlie Covington says
Thank you! I am not using ACF, but I was able to use your function on my own custom meta-field all the same. It works just like I wanted.
JiveDig says
Great to hear! Thanks.
Myles says
Here’s some code I wrote that has support for handling it through the `pre_get_avatar_data` filter in WordPress 4.2+ and handles when objects are passed instead of user ID or email, with fallback to `comment_author_email` if unable to get `user_id` from comment object.
This is specifically for only returning the URL to an image, basically to set the user’s avatar based on a value set in the user’s post meta:
https://gist.github.com/tripflex/3190b9b3b484f99c0a4ba4f6c59cb44f
JiveDig says
Cool thanks!
Herrfischer says
Holy Sh** this is awesome. Btw. in your image above the ACF field is named “tsm_local_avatar” but in the code for the functions.php it’s named “cfm_avatar”, that’s why it didn’t worked for me on first try.
JiveDig says
Whoops! Good catch. Last time I updated the snippet I forgot to use the same key… fixed.
Robert Andrews says
This is beautiful.
But I noticed the code throws a “Notice: Undefined variable” for $user in a strange place – the avatar for a user in “Recent Comments”, on the “Activity” box on a site’s backend Dashboard.
Adding “$user = null;” at the start of your code seems to get rid of the notice.
JiveDig says
Good catch Robert. I actually hit this too at some point and updated my snippet locally but not here. I just fixed it. Thanks.
Robert Andrews says
The function seems to kill off the ability of get_avatar to take an array of arguments, which is its fifth parameter (https://codex.wordpress.org/Function_Reference/get_avatar)
How could this be re-implemented?
In my case, I would want to apply a class to the avatar in some places but not in others. That is …
array( ‘class’ => array( ‘float-left’) )
… on author.php, but not in other places where the avatar is called.
So hard-coding the class in the filter is a bit limiting.
How can I get around this by supporting placing of args like class in the get_avatar call again?
Thanks!
JiveDig says
Hi Robert, if you look at the source code for `get_avatar()` in `/wp-includes/pluggable.php` you can rebuild as much of that functionality as you need. You can see the `$args` being used to build the final markup/output. You can include as many or as few of the args as you may need in your project.
Robert Andrews says
I found a solution at https://wordpress.stackexchange.com/questions/287395/how-to-restore-args-for-get-avatar-custom-class
Jenessa says
Hey Mike,
First of all this is super slick.
Secondly, is there a way I could make this work on the front end as well?
Nelson says
Thank you very much, nice job!!
I just have a question, when I go to wp-admin/users.php, the avatar is not showing up, do you know hot to solve it?
Thanks!
JiveDig says
It should work there. As long as your code/filter is running in functions.php or somewhere else that affects the admin it should work the same.
Brent Alexander says
YAS. This is my new favorite thing! Use it on our blog!
Ugur says
Hey! Thank you so much for sharing this solution.
Simple Local Avatars is using “simple_local_avatar” meta_key and I set the field name “simple_local_avatar” both in code and filter. All other settings are the same as your example. Did you check your solution it recently?
Thanks.
JiveDig says
Are you referring to the plugin Simple Local Avatars? That plugin does this sort of thing already, so you wouldn’t need to run any additional code. We still use this code all the time on various sites.
Ugur says
Hey, thank you for the reply. I think I was not clear, let me explain again: In your example, you used Simple Local Avatars as a plugin who responsible for corp, etc. the image. So, I checked the database and saw that it uses “simple_local_avatar” as a meta_key.
– Then I changed my custom filed name to “simple_local_avatar”
– And used your filter in functions.php (changed the field name as you mentioned in the code)
– And paste the field’s functions into functions.php as well.
Then I tested. no luck. Am I missing something here?
Thanks.
ugur says
By the way, I am using this for user registration with ACF Pro. I mean I’m not trying to change an avatar. I am trying to upload and assign to a new user.
violet says
Hi there,
Since I need to use ACF for registration and now there’s a plugin for front-end ACF forms for Elementor, I was finally willing to learn about child themes and messing with functions.php. Have done all that. Am not getting any errors. Avatars are uploading via ACF and visible on admin view of profile pages, but…. no avatars…
Can you advise?
deepak says
I also have same issue . any solution for this ?
Snake93 says
Hi, same problem here, found a solution?
Ely says
Can I use your code also with the WP User Avatar plugin?
https://nl.wordpress.org/plugins/wp-user-avatar/
I tried it but it’s not working.
Thank you.
Ely
Ely says
How can I also publish the thumbnail on my user profile page or on other locations?
Hugo Arturo says
hola si uso una imagen dinámica como “user profile picture” no logoro verla en backend alguna ayuda
Hugo Arturo says
checo con el inspector de google y apubta a esta ruta
gracias
Hugo Arturo says
buend ia escrino péro nunca contesta