Contents
Overview
This article is a complete, practical, copy-paste ready guide to adding extra fields to WordPress user editing screens (both admin profile edit and front-end registration) using PHP. It covers:
- How to display fields on the profile and new-user pages
- How to validate and save submitted values securely
- How to add fields to front-end registration and validate them
- Example field types: text, textarea, checkbox, select and file upload (avatar)
- How to expose user meta through the REST API
- Best practices and common pitfalls
Principles and WordPress hooks used
Do not alter core database tables. Use user meta (get_user_meta / update_user_meta). Use the profile display hooks to inject form fields and the save hooks to persist them. Always sanitize input, escape output, and verify nonces and capabilities.
- Display profile fields (admin): show_user_profile, edit_user_profile
- Save profile fields (admin): personal_options_update, edit_user_profile_update
- Display new-user form (admin): user_new_form
- Register front-end fields: register_form
- Validate front-end registration: registration_errors
- Save on registration or any new user creation: user_register
- Validate admin-created users: user_profile_update_errors
- Expose meta in REST: register_meta / register_rest_field
Minimal working example (text field) — Admin profile save
This example shows a simple phone number field added to the admin profile page and saved to user meta. It demonstrates nonce usage, capability check, proper sanitization and escaping.
ID, uef_phone, true) ?>
class=regular-text /> |
What this does and why
- show_user_profile and edit_user_profile are used to render the field for the current user and when an admin edits another user.
- personal_options_update and edit_user_profile_update save the data on profile submission.
- wp_nonce_field wp_verify_nonce protect against CSRF.
- current_user_can(edit_user, user_id) prevents unauthorized updates.
- sanitize_text_field stores clean text and esc_attr is used for safe output.
Front-end registration: add field, validate, save
If you need the same field on the regular registration form, hook into register_form, registration_errors and user_register. Below is a complete example for adding the phone field to the front-end registration, validating it and saving it.
add(uef_phone_error, __(ERROR: Please enter a phone number.)) } else { phone = sanitize_text_field(_POST[uef_phone]) // Example simple validation (adjust pattern to your needs) if ( strlen(phone) < 6 ) { errors->add(uef_phone_error_short, __(ERROR: Phone number too short.)) } } return errors } // Save phone after user is created add_action(user_register, uef_user_register) function uef_user_register(user_id) { if (isset(_POST[uef_phone])) { update_user_meta(user_id, uef_phone, sanitize_text_field(_POST[uef_phone])) } } ?>
Admin new-user form
To display custom fields when an admin creates a user in wp-admin (Users rarr Add New), hook user_new_form and validate with user_profile_update_errors. Save using user_register.
Advanced example: checkbox, select, textarea, and file upload (avatar)
This section provides snippets for different form controls and a file upload handled via the WordPress media API to associate an attachment ID with user meta.
Checkbox and select rendering saving
ID, uef_agree_terms, true) color = get_user_meta(user->ID, uef_fav_color, true) ?>
/> | |
File upload (use WordPress Media API) — example
File uploads must use the WordPress admin media handling functions. On profile pages in wp-admin, file uploads are allowed. The example below saves the attachment ID in user meta.
ID, uef_avatar_id, true) ?>
|
Expose user meta in the REST API
To include your custom user meta on REST requests (wp/v2/users or wp/v2/users/
string, single => true, show_in_rest => true, auth_callback => function() { return current_user_can(list_users) } // adjust capability )) } ?>
Alternatively, use register_rest_field if you want a custom getter and schema.
Best practices and security checklist
- Prefix meta keys: Use a unique prefix (eg. uef_ or myplugin_user_). Prevent name collisions.
- Sanitize on input: sanitize_text_field, sanitize_email, esc_url_raw, wp_strip_all_tags, intval, floatval as appropriate.
- Escape on output: esc_attr, esc_html, esc_url when rendering fields.
- Nonce protection: Use wp_nonce_field in forms and wp_verify_nonce on save.
- Capability checks: current_user_can(edit_user, user_id) before saving admin edits.
- Validation: Use registration_errors and user_profile_update_errors to add errors that are shown to the user when appropriate.
- Use WordPress APIs for files: media_handle_upload and related functions to ensure files are processed safely.
- REST exposure: register_meta with show_in_rest and an appropriate auth_callback to avoid leaking private data.
- Localization: Wrap user-visible strings with translation functions when converting this into a production plugin (e.g. __()).
Multisite notes and capabilities
In multisite, user capability flow can vary. Check current_user_can(create_users) for network-level creation or map meta visibility carefully. Be aware of where a users profile edit screen appears (network admin vs site user edit). If your field is sensitive, restrict REST exposure and who can read it.
Troubleshooting and FAQs
-
Form value not saved
Ensure your save hook runs (personal_options_update / edit_user_profile_update). For new users created via admin, use user_register for saving, and user_profile_update_errors for validation. -
Files failing to upload
Ensure you included the required files: wp-admin/includes/file.php, media.php, image.php before calling media_handle_upload. Also check PHP upload limits and file permissions. -
Value not visible via REST
Use register_meta(user, meta_key, array(show_in_rest => true, …)) during init. -
Nonce failing
Nonce fields must be printed on the same page and verified on the same request. Ensure the field name used in wp_nonce_field matches the name you verify.
Hook quick reference
Hook | When to use |
---|---|
show_user_profile / edit_user_profile | Render profile fields in admin (own profile and edit other users) |
personal_options_update / edit_user_profile_update | Save profile fields from admin profile form |
user_new_form | Render fields on admin Add New User screen |
user_profile_update_errors | Validate admin-created users |
register_form | Add fields to front-end registration form |
registration_errors | Validate front-end registration |
user_register | Save data when a user is created (admin or front-end) |
register_meta | Expose user meta to REST API safely |
Full production-ready plugin example (complete)
The following is a consolidated, production-ready plugin file that demonstrates multiple field types, proper sanitization, nonce protection, REST registration (phone), admin and front-end handling, plus avatar upload. You can save this as a single PHP file inside wp-content/plugins/ and activate it for testing. Adjust strings, validation and meta keys to fit your needs.
ID, uef_phone, true) bio = get_user_meta(user->ID, uef_bio, true) agree = get_user_meta(user->ID, uef_agree_terms, true) color = get_user_meta(user->ID, uef_fav_color, true) avatar_id = get_user_meta(user->ID, uef_avatar_id, true) ?>
class=regular-text /> | |
/> | |
|
add(uef_phone_error, __(ERROR: Please enter a phone number.)) } else { phone = sanitize_text_field(_POST[uef_phone]) if ( strlen(phone) < 6 ) { errors->add(uef_phone_error_short, __(ERROR: Phone number too short.)) } } return errors } add_action(user_register, uef_user_register_save) function uef_user_register_save(user_id) { if (isset(_POST[uef_phone])) { update_user_meta(user_id, uef_phone, sanitize_text_field(_POST[uef_phone])) } } // ---------- Register meta for REST ---------- add_action(init, uef_register_meta_for_rest) function uef_register_meta_for_rest() { register_meta(user, uef_phone, array( type => string, single => true, show_in_rest => true, sanitize_callback => sanitize_text_field, auth_callback => function() { // Only allow authenticated users to see user meta via REST in this example return is_user_logged_in() }, )) } ?>
Extra tips
- When adding many fields or grouping fields, consider using a settings page for configuration and keep user meta keys consistent.
- Use nonces with unique names if you have multiple forms on a page so verification distinguishes them.
- If you need complex validation, move that logic into separate functions to keep hooks concise.
- If other plugins/themes need access to these fields, document the meta keys and preferred data types.
- When using media_handle_upload, remember attachments are stored in the global media library. Clean-up attachments if users are deleted, if required, to avoid orphan files.
Resources
- get_user_meta()
- update_user_meta()
- WordPress Users: Plugin Developer Handbook
- REST API meta documentation
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |