Put user custom field on the user account page

Someone wants user custom fields on the account page (they don’t like the profile page for reasons).

It seems like I should be able to do this in a theme component.

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/templates/preferences/account.hbs#L207

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/templates/preferences/profile.hbs#L24-L28

common/head_tag.html:

<script type="text/x-handlebars" data-template-name="/connectors/user-preferences-account/lc-ucf">
<div style="height: 25px; width: 25px;background: blue"></div>
<h3>Custom User fields for {{ model.username}}</h3>
This is uf: {{model.user_fields}}.
{{log "THIS" model.user_fields}}
{{#each model.user_fields |uf|}}
{{log "THISTHISTHIS" this}}
  <div class="control-group">
    {{user-field field=uf.field value=value}}
  </div>
{{/each}}
<div class='clearfix'></div>
</script>

I can’t seem to access the user custom fields, though.

I get my blue box.

I see that I can access model.username.

In the console log I see:

THIS {3: "STEM Professional (industry)"}

image

I’m sure I’m doing something silly, but after reading the excellent Developer’s Guide to Themes a bunch of times. I’m stumped.

1 Like

Well, I’m doing again the thing where I post about some problem I’m trying to solve…

Now I’m trying to solve the same problem in a plugin. I’ve created myplugin/assets/javascripts/discourse/connectors/preferences/account/user-custom-controls/my-stuff.hbs and that’s added some stuff to the page (just like before!) and again I don’t know how to (1) get the data, (2) tell ember (?) that it should update the field when the form is saved.

I think now that maybe I need to override or add to account.js.es6 and add the user_fields to this.saveAttrNames so that it’ll know to save them if it updates and also get data into userFields.

I’ve poked at a bunch of plugins, but can’t quite get it.

1 Like

Ok, I made it work but its somewhat tricky.

Create a connector class with this code.

import { set } from "@ember/object";
import EmberObject from "@ember/object";

export default {
@discourseComputed("model.user_fields.@each.value")
  publicUserFields() {
    const siteUserFields = this.site.get("user_fields");
    if (!isEmpty(siteUserFields)) {
      const userFields = this.get("model.user_fields");
      return siteUserFields
        .filterBy("show_on_user_card", true)
        .sortBy("position")
        .map(field => {
          set(field, "dasherized_name", field.get("name").dasherize());
          const value = userFields ? userFields[field.get("id")] : null;
          return isEmpty(value) ? null : EmberObject.create({ value, field });
        })
        .compact();
    }
  },
}

On the connector template,

{{#if publicUserFields}}
        <div class="card-row fifth-row">
          <div class="public-user-fields">
            {{#each publicUserFields as |uf|}}
              {{#if uf.value}}
                <div class="public-user-field {{uf.field.dasherized_name}}">
                  <span class="user-field-name">{{uf.field.name}}:</span>
                  <span class="user-field-value">{{uf.value}}</span>
                </div>
              {{/if}}
            {{/each}}
          </div>
        </div>
{{/if}}
6 Likes

@pfaffman did it work ?

2 Likes

I’ve not had a chance to try it yet, but I’m guessing that it will. So much that I have yet to learn. Thanks so much for your generosity! I can’t thank you enough, but I’ll try in a while when I try it out

3 Likes