How Can I Create WordPress User Profiles with Frontend Editing and Custom User Fields?

Laurel Johnson

In this post, we’ll create custom WordPress user profiles that users can update from the frontend of your site.

We’ll be using a well-maintained WordPress plugin called Theme My Login (TML) that gives you a head start on creating custom login pages and front-end user profile editing.  It’s got filters and action hooks so it’s extensible and you can easily take their default templates and make them  your own. It’s also got settings that let you hide the WordPress dashboard from regular users, send custom emails to new users, and more.  Then we’ll combine TML with Advanced Custom Fields (ACF) user fields to create a custom user experience.

First up, use ACF to make a field group with rules to display if “current user role is equal to admin” and “current user is equal to viewing backend” and “user form is equal to all”.  This will create a field group that is accessible to administrators viewing Users in the WordPress backend.  The fields will still be accessible to your front-end users but we’ll be adding the fields to our login and profile page templates ourselves so we have more control. (The other option is to let ACF display the fields automatically via the “register-form” and “show_user_profile” hooks in your templates.)

Next, add your custom fields to the field group you just created.  This could be anything from a shipping address to a preferred method of contact — any additional information that you want to gather from your users.  Also keep in mind that you can choose which fields the users themselves will have access to on the registration and profile templates so you could create fields that are only viewable by yourself and other admin users.

Now add the new fields to your user profile and registration forms for users to access via the frontend of your site.  TML knows to look for customized templates in your active theme directory before going to the default templates that come with the plugin. So all you need to do is copy the templates you want to customize from the plugin directory into your theme folder and edit them there. To add the new fields, follow the structure of the the existing fields making sure to update the name, id and value attributes to match your new field name.  You can add headers and subheaders and do whatever you need to create the user experience you want — as long as you edit the templates in your theme directory, they won’t be overwritten when you update the plugin.

Lastly, the fields you added to your templates need to be saved when a user submits the form.  To do this, we’ll add a couple functions for TML to run on the appropriate action hooks.  TML knows to look for a file called theme-my-login-custom.php in the plugins directory.  Create this file and make sure to save it to the wp-content/plugins directory — if you were to put it inside the theme-my-login directory, it would get overwritten next time you update.

If you need custom validation on your new fields, add them to a filter like this:

function tml_registration_errors( $errors ) {
   if ( empty( $_POST['user_street_address_1'] ) )
      $errors->add( 'empty_user_street_address_1', '<strong>ERROR</strong>: Please enter a street address.' );
   return $errors;
add_filter( 'registration_errors', 'tml_registration_errors' );

Now add your custom fields to the actions that will save your user data when they register or update their profile:

function tml_user_register( $user_id ) {
   if ( !empty( $_POST['user_street_address_1'] ) ) 
      update_user_meta( $user_id, 'user_street_address_1', $_POST['user_street_address_1'] );
  if ( !empty( $_POST['user_street_address_2'] ) ) 
      update_user_meta( $user_id, 'user_street_address_2', $_POST['user_street_address_2'] );   
add_action( 'user_register', 'tml_user_register' );

function tml_user_update( $user_id ) {
   // this is a required field
   if ( !empty( $_POST['user_street_address_1'] ) )
      update_user_meta( $user_id, 'user_street_address_1', $_POST['user_street_address_1'] );

   // this field is optional
   if ( !empty( $_POST['user_street_address_2'] ) ) : 
     update_user_meta( $user_id, 'user_street_address_2', $_POST['user_street_address_2'] );
   else : 
     // delete the user meta if the field is empty
     delete_user_meta( $user_id, 'user_street_address_2' );
add_action( 'profile_update', 'tml_user_update' );

In case you’re wondering about security (and you should be!)… it’s an important security practice to sanitize your data whenever you’re saving input from users. Because we’re using the update_user_meta() function, WordPress is sanitizing our data for us. For a good overview of data sanitization practices in WordPress, see this tuts+ blog post about sanitization.

You should now be able to test your forms and make sure they’re behaving as intended.  If something isn’t saving or updating, double check that the input names in your templates match the ACF fields they’re associated with.

Last updated by on .

12 thoughts on "How Can I Create WordPress User Profiles with Frontend Editing and Custom User Fields?"

  1. henry says:

    Hi, Thanks for this. Looking to do the same but I’m lost at saving the fields. To save you used:

    if ( !empty( $_POST[‘user_street_address_1’] ) )
    update_user_meta( $user_id, ‘user_street_address_1’, $_POST[‘user_street_address_1’] );

    For ‘user_street_address_1’ value is that the field name?

    Say I have an ACF field name called user_address but the field also has a value of something like field_58ec0c68e68cc. Using your method this will save ‘user_address’ with out using this id “field_58ec0c68e68cc”?

    I’ve seen somethig like this and was wondering if it was the same thing.

    if ( isset( $_POST[‘fields’][‘field_58ebfc0d7d6d4’] ) )
    update_user_meta($user_id, ‘owner_address1’, $_POST[‘fields’][‘field_58ebfc0d7d6d4’]);

    Any help is appreciated. Thanks.

  2. Maysa says:

    customize error messages in a neat way for users on registration form

  3. Maysa says:

    I want to customise error messages on registration form and to keep entered data after throwing errors

  4. Laurel says:

    Hi Henry,

    Yes, ‘user_street_address_1’ in the example is the name for the ACF field being saved in the example. Advanced Custom Fields maps the pretty field names that you create to unique field name such as ‘field_58ebfc0d7d6d4’ like you’ve seen in other examples. I prefer to use the pretty field names because it’s easier to immediately see which field you’re working with. I’m not aware of any issues with using the unique field name generated by ACF but like I said, I usually leave those alone. I hope that helps – let me know if you have any follow up questions!

  5. Laurel says:

    Hi Maysa,
    When throwing validation errors, Theme My Login maintains the data that’s been entered so that users only have to enter the missing information. If that’s not working, make sure the new fields you’ve added have the value set to $template->the_posted_value( ‘name_of_your_field’ ), like this:

    <input type="text" name="user_email" id="user_emailthe_instance(); ?>” class=”input” value=”the_posted_value( ‘user_email’ ); ?>” />

    Also, make sure you’re not missing anything from your custom template by checking it against the original from the plugin.

  6. Amanda says:

    Hi and thanks for the guide,
    I’m not following how you are adding the ACF fields to the TML templates. I know how to display already entered ACF data (from post or page), but not how to push the fields themselves on a template.

    Do you have any links that shows me how to do this?

    At the moment I’m copying the already existing -fields that TML has in their templates and adding the information that way, not accessing ACF in any way.

  7. Amanda says:

    Actually, never mind the above 🙂 I can see now that you advice to use the same structure as the template, like I’ve done.

    Another question, when are the “tml_registration_errors” ever used/seen?

  8. Exactly what I was looking for to create custom user profile. I’ll give ThemeMyLogin a try and see if that solve my problem.

  9. Laurel Johnson says:

    Great! I’m glad you’ve found this useful!

  10. suresh kumar says:

    I am working on a medical reporting site in wordpress, where the requirement is that admin can upload a seperate .pdf file to different users’ profile & only the profile owner can download it

  11. Laurel Johnson says:

    Hi Suresh, you could have a Repeater field using ACF that would let admins upload pdfs to a user’s profile and then customize the user profile template to display that field. I recommend looking at the documentation for both plugins as good starting place.

What Are Your Thoughts?

Your email address will not be published. Required fields are marked *