How do I add custom user fields to my theme?
-
If you have a custom theme that introduces custom user fields into the edit page, you might have noticed that the fields don't seem to show up on the frontend even if they're saved in the database.
Likewise, if you have some custom data you want to maintain on a per-user basis, and you tried usinguser.updateProfile
, you might've noticed that your fields don't seem to save.The reason for this behaviour is that the the user fields getter and setter are protected so that values in the user hash are not unintentionally overwritten, or that fields are retrieved that should not be.
For example:
nodebb-plugin-foobar saves a private user token in the user's hash. It is not meant to be retrieved. Another plugin calls
user.getUsersFields()
and that method naively returns everything in the user hash. The private key would then be considered leaked if it is accidentally exposed to the end user, even if unintentionally.Getter (retrieving user data)
If you've saved a custom field into the user hash and you wish to retrieve it via
User.getUsersFields()
, you will have to explicitly whitelist it by attaching a hook listener tofilter:user.whitelistFields
. That plugin hook sends in{ uids, whitelist }
, whereuids
is an array of uids (requested by the calling script), andwhitelist
, which is an array containing user field properties.You can add a new entry to the whitelist thusly:
plugin.json
{ ... "hooks": [ { "hook": "filter:user.whitelistFields", "method": "addUserField" }, ] ... }
library.js
library.addUserField = async ({ uids, whitelist }) => { whitelist.push('customField'); return { uids, whitelist }; };
After doing so, a call to
user.getUsersFields(uids, ['customField']);
will have thecustomField
property show up as it has been explicitly allowed.Setter (saving user data)
Setting user data is comparatively simpler. We recommend using the
user.updateProfile()
method, as that has some sanity checks and special handling for certain fields. To allow the saving of a certain field, you will need to pass it in to the third argument ofuser.updateProfile()
:await User.updateProfile(callerUid, { uid, customField: 'value', }, ['customField']);
-
-
-
-
Will a similar approach also apply for custom data added to category, group, post, topic? If so that would make life so much easier for me, literally! I can't let go nodebb especially seeing you work so hard on getting it to work with fediverse, it opens up so many possibilities and is better for the internet community as a whole in this era of corporate and govt censorship and restrictions on free-speech!
-
@solmak most first-class objects' libraries expose a getter and setter as well, and they're likely not as locked down as the user ones.
You can usually find them in
src/(something)/data.js
and can be called from plugins as well. -
-