How can I modify my following code to add some description text under the input fields? I tried modifying it as you can see with the facebook url field but the text shows up under the field label and not the actual input field --

function modify_contact_methods($profile_fields) {
    // Add new fields
    $profile_fields['address'] = 'Address';
    $profile_fields['city'] = 'City';
    $profile_fields['state'] = 'State';
    $profile_fields['zipcode'] = 'Zip Code';
    $profile_fields['phone'] = 'Phone Number';
    $profile_fields['fax'] = 'Fax';
    $profile_fields['gplus'] = 'Google+ URL';
    $profile_fields['twitter'] = 'Twitter URL';
    $profile_fields['facebook'] = 'Facebook URL <br /><span style="clear:both;">Ex: www.facebook.com/username</span>';
    // Remove old fields

    return $profile_fields;
add_filter('user_contactmethods', 'modify_contact_methods');

Based on information gathered HERE and HERE; I was able to put something together.

First... abandon your first approach. It will add a field value, yes. But it will not allow you to add a descriptive field.

Instead, we need to create an entire new table tag in the structure that gets populated from WordPress. To do so, let's use this function:

function my_custom_user_profile_fields( $user ) {
    <table id="facebook_user_field_table" class="form-table">
        <tr id="facebook_user_field_row">
                <label for="facebook_field"><?php _e('Facebook URL', 'your_textdomain'); ?></label>
                <input type="text" name="facebook_field" id="facebook_field" value="<?php echo esc_attr( get_the_author_meta( 'facebook_field', $user->ID ) ); ?>" class="regular-text" /><br />
                <span class="description"><?php _e('Please enter your Facebook profile url.', 'your_textdomain'); ?></span>
add_action( 'show_user_profile', 'my_custom_user_profile_fields' );
add_action( 'edit_user_profile', 'my_custom_user_profile_fields' );

That will define our new tr element, and populate it with the necessary structure. You may change the field label and description to suit your needs.

NOTE: This will only create our new tr element, and place it at the bottom of the "About Yourself" section. In order to 'place' the new tr element where we want (ie the "Contact Info"), we have to use a bit of jQuery:

function my_facebook_field_placement_js() {
    $screen = get_current_screen();
    if ( $screen->id != "profile" && $screen->id != "user-edit" ) 
    <script type="text/javascript">
        jQuery(document).ready(function($) {
            field = $('#facebook_user_field_row').remove();
            parent = $('#url').closest('tr');
add_action( 'admin_head', 'my_facebook_field_placement_js' );

This code will take our new tr element, and add it BEFORE the "WEBSITE" field that is generated by WordPress.

NOTE: See how we are hooking to admin_head here? We want to make sure this doesn't run on every admin page. So, the first part of this code block will check the current page, and only run the code if we are on the profile page.

Now... that's great. Placement is Perfect!! But wait... now our data is not saving when we update the fields. Fret not!! We have another hook for that:

function my_save_custom_user_profile_fields( $user_id ) {
    if ( !current_user_can( 'edit_user', $user_id ) )
        return FALSE;

    update_user_meta( $user_id, 'facebook_field', $_POST['facebook_field'] );
add_action( 'personal_options_update', 'my_save_custom_user_profile_fields' );
add_action( 'edit_user_profile_update', 'my_save_custom_user_profile_fields' );

This will update the field, and store it in the user meta table. Then, whenever you need to access this value from your template; just use the get_user_meta function.

  • 1
    Another good one, +1. I'd do a micro-optimization: if( !in_array( get_current_screen()->id, array('profile','user-edit') ) ) return;
    – brasofilo
    Oct 18 '13 at 20:17
  • 1
    Wow! - "micro-whatchamacallit".. awesome. I've always declared get_current_screen() as a variable first. Very cool!! Thank you.
    – josh
    Oct 18 '13 at 23:54
  • Well, that's micro-micro optimization, but if we're calling the function only once, then goodbye var... I only arrived at this recently, nice you liked :)
    – brasofilo
    Oct 19 '13 at 1:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.