How to add custom profile fields to a NodeBB forum ?

Technical Support
  • Hi !

    I just switched from phpBB to nodeBB.
    I must say as a disclaimer that I'm a front-end dev with little to no experience on consoles, using Node.js, error logs, etc etc - and english isn't my first language. Please talk to me as though I am 5. 😅

    I need to add custom fields to users profile because I'm building a textual RPG on forum. I found a plugin, nodebb-plugin-ns-custom-fields, but it seems like it's not compatible with the latest NodeBB version.
    If I'm not mistaken, it's not possible to add any custom fields directly on the ACP without any plugin : is that right ?

    If so, does someone have any hint on how I could achieve that ?

    Thank you !

  • 1 1019-h marked this topic as a regular topic on
  • Paging @Nicolas 😄

    That plugin might be compatible with v2.x, if I recall correctly, he does still use and maintain those plugins (although I could be mistaken).

    But... yes, that's correct, you can't add user profile fields from the ACP, you'll need a plugin to do so.

  • Oh I actually already made an issue on github, he said that the plugin was very likely to be incompatible with my NodeBB version (2.8.6).

  • Okay so I dug a little and was searching for something like an User model to edit so I can add my custom fields, but I seem to be unable to find it. I saw a whitelist for fields, but that's all ...

    Does anyone know where to start at least ? Even if it's not on the ACP & a whole plugin, it's not that big deal if I can edit the files myself.

  • @1019-h I'm writing a Developer FAQ about it. I don't recommend you edit core files, but you can write a plugin that can update the necessary fields.

  • @julian Sorry, just to be clear : you're writing a Developer FAQ on how to add custom fields or ... ? sorry I'm just making sure I understood right.
    I'd love to write a plugin but even with the quickstart plugin, I really don't know where to start on how I could achieve custom fields 😞

  • Sorry, I'm still trying to do this and since I saw many topics on the subject, I thought I'd share my process, even if I think I'm not qualified to do this - maybe it'll help someone some day.

    I found in src\user\data.js :

    	User.setUserField = async function (uid, field, value) {
    		await User.setUserFields(uid, { [field]: value });
    	};
    
    	User.setUserFields = async function (uid, data) {
    		await db.setObject(`user:${uid}`, data);
    		for (const [field, value] of Object.entries(data)) {
    			plugins.hooks.fire('action:user.set', { uid, field, value, type: 'set' });
    		}
    	};
    

    src\user\profile.js :

        User.updateProfile = async function (uid, data, extraFields) {
    		let fields = [
    			'username', 'email', 'fullname', 'website', 'location',
    			'groupTitle', 'birthday', 'signature', 'aboutme',
    		];
    		if (Array.isArray(extraFields)) {
    			fields = _.uniq(fields.concat(extraFields));
    		}
    		if (!data.uid) {
    			throw new Error('[[error:invalid-update-uid]]');
    		}
    		const updateUid = data.uid;
    
    		const result = await plugins.hooks.fire('filter:user.updateProfile', {
    			uid: uid,
    			data: data,
    			fields: fields,
    		});
    		fields = result.fields;
    		data = result.data;
    
    		await validateData(uid, data);
    
    		const oldData = await User.getUserFields(updateUid, fields);
    		const updateData = {};
    		await Promise.all(fields.map(async (field) => {
    			if (!(data[field] !== undefined && typeof data[field] === 'string')) {
    				return;
    			}
    
    			data[field] = data[field].trim();
    
    			if (field === 'email') {
    				return await updateEmail(updateUid, data.email);
    			} else if (field === 'username') {
    				return await updateUsername(updateUid, data.username);
    			} else if (field === 'fullname') {
    				return await updateFullname(updateUid, data.fullname);
    			}
    			updateData[field] = data[field];
    		}));
    
    		if (Object.keys(updateData).length) {
    			await User.setUserFields(updateUid, updateData);
    		}
    
    		plugins.hooks.fire('action:user.updateProfile', {
    			uid: uid,
    			data: data,
    			fields: fields,
    			oldData: oldData,
    		});
    
    		return await User.getUserFields(updateUid, [
    			'email', 'username', 'userslug',
    			'picture', 'icon:text', 'icon:bgColor',
    		]);
    	};
    

    I've also tried to read three plugins that were interesting to me, see how they did it : Cash mod, OpenFantasy & Custom Fields. But eventhough I tried a lot I haven't been able to reproduce anything they did in the quickstart plugin. Even my console.log("hello world") wasn't working, hahah. They're not working either anyway...

    I know it's not good to edit core files, but I'm really getting frustrated. If I can't add custom fields, I can't use NodeBB and I'll be back on Forumotion, which is a pain in the ass.

    I thought of creating another table which would have all the custom fields and a column that would get the UID of the user those fields are related to. But I was having such a hard time finding how to show tables in MongoDB, especially user tables and switched to PostgreSQL, only to find out there isn't any user table, just data stored in a row...

    So yeah, is there anyone to give me like hints on how I could do that ? I know I have to do a plugin, but I just don't know where to start and I can't seem to replicate what others did before.

    Thanks

  • @1019-h Are you looking to add just one field, or multiple fields? Depending on scope might be worth talking with a backend developer to get this built for you (either someone here or via us at [email protected]).

  • Multiple fields, but yeah it could be a solution. I'm gonna look into that, thank you !


Suggested Topics