Custom user fields for plugins


(Sam Saffron) #1

I just added support for custom user fields:

https://github.com/discourse/discourse/commit/a3b2b4bacac92b0dc5ceaf6892f782f4b5584a57

In a nutshell:

> me = User.find_by(username: 'sam')
> me.custom_fields["title"] = "Mr"
> me.save
> me = me.find(me.id)
> me.custom_fields["title"] == "Mr"

This feature is mainly there for plugins that need to extend the user model with a bunch of extra fields. I will also cook up a sample on how to get the serializers to pass on what data you need.

This is integrated into SSO. You can send in custom fields by prefixing them with custom., this can be very handy for various integrations:

Eg: discourse/session_controller_spec.rb at a3b2b4bacac92b0dc5ceaf6892f782f4b5584a57 · discourse/discourse · GitHub

 it 'allows you to create an account' do
      sso = get_sso('/a/')
      sso.external_id = '666' # the number of the beast
      sso.email = 'bob@bob.com'
      sso.name = 'Sam Saffron'
      sso.username = 'sam'
      sso.custom_fields["shop_url"] = "http://my_shop.com"
      sso.custom_fields["shop_name"] = "Sam"

      get :sso_login, Rack::Utils.parse_query(sso.payload)
      response.should redirect_to('/a/')

      logged_on_user = Discourse.current_user_provider.new(request.env).current_user

      # ensure nothing is transient
      logged_on_user = User.find(logged_on_user.id)

      logged_on_user.email.should == 'bob@bob.com'
      logged_on_user.name.should == 'Sam Saffron'
      logged_on_user.username.should == 'sam'

      logged_on_user.single_sign_on_record.external_id.should == "666"
      logged_on_user.single_sign_on_record.external_username.should == 'sam'
      logged_on_user.active.should == true
      logged_on_user.custom_fields["shop_url"].should == "http://my_shop.com"
      logged_on_user.custom_fields["shop_name"].should == "Sam"
      logged_on_user.custom_fields["bla"].should == nil
    end

Deprecating hstore meta_data fields
User custom field with plugin
Custom field for 'create an account'
Reddit Style picture thumbnail on the left
A thought about GCM plugin for push notification
Difference between Using Postgres instead of working directly with database
Migrated password hashes support
Custom Layouts Plugin
Official Single-Sign-On for Discourse (sso)
(Erlend Sogge Heggen) #2

Super handy. Once my community moves to Discourse we’ll definitely want something like:

sso.custom_fields["github_username"] = "erlend_sh"

(Adam Capriola) #3

Awesome.

  1. Is “Web Site” (located in user preferences) a custom field? It isn’t listed in the accessors here for SSO, so I am not sure how to tap into it.

  2. This is a little off-topic, but is there currently or will there be extensibility for groups integrated with SSO?


(Chris Allick) #4

I am not 100% sure this is what you are posting about here, but I’d like to customize the fields shows on the user page.

For example, one of them is “website.” I’d like to add my own. Is there a plugin for this or do I need to change the code? If so, is this github link pointing me to where i can do that?


(Tyler Gillies) #5

Did you ever figure out how to do this?


(eriko) #6

Is it possible to deliver the person back to the page they clicked login from? In my case they would have been immediately redirected to login on any page (or email link) as the site is locked down.


(Jeff Atwood) #7

That is not what Sam is talking about here at all, but we do have Admin, Customize, User Fields now. That is what you are referring to.

This topic is about user data storage for plugins and extensions.


(Robert Dean) #8

Is it possible to add a custom user field that allows a user to upload additional photos to their profile? Currently the options are text field or confirmation.


(Fraser Redmond) #9

I can’t get the custom fields from SSO to work… or at least I don’t think it’s working.

I’ve tried passing in combinations of the following:

  • &custom.userId=1
  • &userId=1
  • &custom.user_field_1=1

I’ve also changed the user’s name as it’s passed in, so I know the SSO is definitely receiving the data.

The 2 places I’ve looked for the custom data to appear is:

I know Jeff said

This topic is about user data storage for plugins and extensions.

Is there any way to see if the custom fields have worked?
(And if it’s one of those 2 places I’ve said above, then any ideas why it’s not working for me?)


(Rafael dos Santos Silva) #10

Hey,

Just tested and sending &custom.user_field_1= works fine through SSO.

You can see if it’s working by setting they as visible on user profile.


(Silver Quettier) #11

Sorry for the necroposting, but I’m using this to massively import users and populating their custom fields in the process.

As @Falco mentionned, I can assign a value to the custom fields created through the interface by assigning a value to user.custom_fields['user_field_1'], for example.

Thing is, when there are multiple custom fields, the “1” is not easy to guess.

Is there a way to do one of these two things:

  • Tell which number a custom field has without digging into the database and the user_fields table?
  • Rather than passing user_field_1 as parameter, calling a pre-built Ruby function that would lookup the custom field number by name? (e.g. user.custom_fields[CoolService.lookup('My Field Name')])

(Rafael dos Santos Silva) #12
user.custom_fields["user_field_#{(UserField.find_by name: 'My Field Name').id}"]

PS.: This is on ruby land.


(Emma Lejeck) #13

Care to share? I can only find examples which use TopicList.preloaded_custom_fields, which doesn’t seem to apply to User

Edit: to be more specific I’m asking especially for on posts


(James Kiesel) #14

A couple examples of how I do in in Babble:

And retort (probably closer to your use case):

NB that those retorts are stored as records in the PostDetail table.


(Emma Lejeck) #15

Hilariously, all of these are 10x more complex than what I’m seeking… all I need is to access an integer custom field on the user and do some datemath with it :confused:


#16

I have been following this;

Which seems to address the issue that has been raised here.

I do not know how to implement it for my forum. Are there “Instructions for Dummies” available?

Thanks


(cpradio) #17

This should be simple enough to understand, yes?


(Lars) #18

Is there a way of accessing external_id in the templates? I can use Customize / HTML/CSS / Some_name / and get it to show custom fields on the profile and the card like facebook URL, twitter handle and other stuff, but I need the external_id to link to my main site…


(Sam Saffron) #19

not at the moment, you would need a plugin for that.


#21

Newbie question - are the custom fields sent each time an authenticated user is directed to Discourse? Or, does this only happen only after they are logged out and attempting to authenticate via SSO again.

Example: If someone adds their Github username inside our app, it will only be sent/updated in Discourse after they are logged out and attempting SSO again, correct?