Adding own avatar provider


(Marcelo Delgado) #1

There is a REST service that I can pass in a username and it will return an avatar that I need to use for my site. Looks something like this:

hxxp://avatarservice.com/[username]/50.png

How would I go about replacing the default Gravatar with this. Is it even possible without major restructuring?


(Vikhyat Korrapati) #2

This is how I did this for Hummingbird (in a plugin):

after_initialize do
  User.class_eval do
    def avatar_template
      # Generate your URL here, with "{size}" where the image size should be substituted.
    end
  end
end

If you also need to customize the size substitution from numbers to something else, we have this (javascript):

Discourse.Utilities.avatarUrl = function(template, size) {
  if (!template) { return ""; }
  if (size <= 25) {
    return template.replace(/\.[a-z]+\?/, '.jpg?')
                   .replace(/\{size\}/g, 'small');
  }
  else {
    return template.replace(/\{size\}/g, 'thumb');
  }
};

(Marcelo Delgado) #3

Thanks this is great! Going to look into creating plugins. This is the first time I read ruby code so some things are hard to understand. Question, how would I reference the username from the avatar_template function to use it to generate the url with?


(Kane York) #4

It’s executing code inside of a User object, so you can just say username.split('cow') etc etc.


(Aselox) #5

Thank you @radq but I have a problem: the plugin is overriding Gravatars and custom avatars so, is there a way to keep the plugin avatar as the default avatar and still give the ability to change avatar (custom or Gravatar) to the users?


(Kane York) #6

Make your code this:

after_initialize do
  User.class_eval do
    def avatar_template
      uploaded_avatar_path || your_code
    end
  end
end

(Aselox) #7

Thank you @riking :blush:

Since I want to override users avatar using my plugin, how can I remove the ability to edit avatars in the account preferences page (which does nothing when my plugin is active)?
I’d like to remove the button next to the avatar in the preferences view.


(Aselox) #8

Hi @riking

Your code doesn’t work anymore with the new avatar system (the one with letters as default). Ho can i make to work it again?

@sam What should I modify to make it work as before?

Thank you


(Aselox) #9

No one? This is critical to me.


(Vikhyat Korrapati) #10

I will be looking into it this weekend, we also need to get this sorted out before upgrading to latest. Will let you know what I come up with if no one replies until then.


(Jeff Atwood) #11

We think adding a new avatar provider should be easier with the new avatar code paths after dropping Gravatar. Let us know if it needs any tweaks to make that happen @radq.


(Sam Saffron) #12

We may want to refactor the UserAvatar class for this, also keep in mind, new system expects that each avatar has an upload id, if it does not stuff will not work right. Don’t just plug avatar templates in. You must make a “real” upload for each avatar.


(Vikhyat Korrapati) #13

This is what I ended up doing:

https://github.com/vikhyat/discourse-hummingbird/commit/4838d7ce9275008059ff631083f52cba2917af0b


(Emma Lejeck) #14

You might want to make this pluggable, it really doesn’t make sense in the context of a larger site integration: you don’t want to be storing two copies of your avatars and processing them twice (in perhaps different ways which confuse the end-user).

Most forums are integrated with a larger site nowadays, so this seems like an important thing to allow replacing.


(Vikhyat Korrapati) #15

@sam We’re having a bunch of issues with avatar uploads on the Discourse side, especially with respect to animated GIFs. Also I would prefer to not have to duplicate avatars in two places.

What exactly would break if I store an avatar template in a custom field and override the avatar template methods in the client and server side?


(Sam Saffron) #16

The new system expects all avatars to be served from:

/user_avatar/meta.discourse.org/radq/{desired_size}/{upload_id}.png

The controller itself takes care of sizing down the upload and ensuring it gets cached forever.

In the past our local avatars were always served full size, that is very inefficient and causes unneeded client side work. It would be extra inefficient for animated avatars.

By expecting an Upload per avatar we can ensure the same pipeline is used for sizing down images and the same caching technique is used and same cleanup routines run.

If I were to add any more avatar providers I would start from the base premise that we expect one upload per avatar and then the rest of the pipeline can remain untouched. I do not want to support serving full size unoptimised images to users requesting a 30px avatar. I do not see why you would want to duplicate the sizing / caching and cleanup logic.

If there is a bug in sizing down animated avatars in core we want that fixed. Not workarounds in place.


(Vikhyat Korrapati) #17

I can make a PR to fix the avatar resizing. In addition to fixing whatever is wrong with animated GIF resizing is it okay if I make it so that only images over a certain size are animated even when animated avatars are enabled? It doesn’t really make sense for the 25x25 avatars on the topic listing to be animated, the images become larger than they need to in terms of file size and also causes high CPU usage because they keep getting redrawn.


(Emma Lejeck) #18

For site integrated forums, it should still be possible to just rip out or stop using features from Discourse and reroute them to the site’s providers of those features, right?

Like, in theory, couldn’t we just override the template and/or model and null or ignore the user’s avatar in the discourse db to achieve what this whole thread is about?

@radq does the PNG transparency fix also fix animated GIFs?


(Aselox) #19

No update yet? I think the ability to add our own avatar provider should be a built-in setting as it’s really crucial to some forums.


(Sam Saffron) #20

I thought @radq got this working