Home > Ideas, programming, WordPress > How to Add an Image Field to Buddypress Extended Profile Fields

How to Add an Image Field to Buddypress Extended Profile Fields

BuddyPress is a plugin that brings social networking capabilities to WordPress. It comes with features such as Friend connections, Activity streams (status posting), Private messaging, Groups and Forums. There is lot’s more you can do with it via BuddyPress Plugins. These are simply WordPress plugins that are compatible with BuddyPress. You can work with BuddyPress as just one component of your WordPress website’s functionality, or you can have it as your central component and completely hide the rest of WordPress. Just like WordPress, BuddyPress is completely open source and almost as flexible.

How BuddyPress Works

1.   Hooks

Being part of the WordPress ecosystem, BuddyPress employs hooks liberally in its implementation. These help theme and plugin developers greatly when it comes to interfacing with BuddyPress in a future-proof manner. When used correctly, the hooks allow developers to write code that doesn’t break on newer versions of BuddyPress.

Among the most important hooks in BuddyPress are:

–  bp_screens:  It processes functions that respond to user input with visual feedback. Basically this is the hook to use when you want to output a page in response to user input. A good example is displaying a list of friends in response to the clicking of the friends menu.

–  bp_actions:  This hook is similar to bp_screens, but does not give visual feedback. A good example of such is when accepting a friend request. This hook is called before bp_screens and we shall use this rule in implementing the image field.

2.   Components

Functionality in BuddyPress is delivered via components. Roughly, a component maps to a feature. For example the Groups feature is handled by the Group component. Components contain the various bp_screens and bp_actions hooks required to respond to user input. A fresh installation of BuddyPress has the following components:

–  Extended Profiles:  maintains user profile details such as name

–  Friend Connections:  allows users to make and accept friend requests

–  Private Messaging:  handles messaging between specific users. Only the users addressed in the messages can view them.

–  Activity Streams:  handles the posting of public statuses and generally tracking the actions of users.

–  Groups:  handles the creation and maintenance of user groups. Users can create groups, invite other users etc.

–  Forums:  this component allows topical discussions to be carried out among users either site-wide or within groups.

3.   Permalinks (pretty urls)

All screens in BuddyPress are accessed through hierarchical urls that are clear to the website visitor. For example, Andrew’s profile can be viewed at example.com/members/andrew/profile/. This kind of url is not new to regular WordPress users. However, the way BuddyPress implements the permalinks is quite different from WordPress. When developing a plugin for WordPress, the plugin developer needs to implement rewrite rules that get incorporated into WordPress’ existing rewrite rules. By implementing the rewrite rules, the plugin developer is given access to parameters that are passed in the url.

In BuddyPress, there’s no need to create rewrite rules since it parses the urls and then stores the various components in the globally accessible $bp object. In the Andrew example, the url is broken into:

–  Component: members

–  Action: Andrew

–  Action variable: profile

This approach allows much greater flexibility in creating custom permalinks for your theme or plugin.

4.   Themes

BuddyPress can be themed just like WordPress. The only catch is that the theme should be BuddyPress compatible. It comes with the BuddyPress Default theme by default which is very closely tied in with the structure of BuddyPress. For this reason, it is advisable to derive your theme from bp-default rather than build a new one from scratch. Due to the close ties between BuddyPress and the bp-default theme, most plugins are constructed with the assumption that they shall be used on the bp-default theme or a derivative (child theme). Applying a theme to BuddyPress is done the same way a theme is applied to WordPress.

Extended Profile Fields

The Extended Profile Fields (XProfile) component handles user profile details. It allows the creation of any number of fields to hold the profile details. This allows BuddyPress to be useable in a wide range of communities. By default the XProfile field types supported are:

–     Single line text

–     Multiline text

–     Date

–     Radio (option) buttons

–     Check boxes

–     Drop-down select list

–     Multi-select list

These field types obviously cover much of what would be required to store user information. However, there’s one critical omission. The image field type. BuddyPress already has the capability to store a user profile image known as the avatar. Therefore if that’s the only image you require for your users then you’re covered. For non-trivial user profiles, there inevitably arises the need to have a field that holds image information in addition to the user avatar. The image could be a company logo for example.

Adding an Image field type

When adding functionality to a platform such as BuddyPress, it’s extremely important not to modify any of its core files. Such an approach allows you to apply newer versions of the platform without having extra steps to update the files you altered. This is one of the main reasons hooks are created on the platform. XProfile  does not come with hooks specifically intended to allow you to add unsupported field types, but it does have enough hooks that can facilitate defining and managing a new field type.

Enough with the talk, now let’s get to the code. All the following code (unless stated otherwise) goes into your theme’s functions.php. The functions are prefixed with 'bpd' to minimize the chances of name collision with other theme/plugin functions.

  1. Announce to XProfile  that you have a new field type – image:
function bpd_add_new_xprofile_field_type($field_types){
    $image_field_type = array('image');
    $field_types = array_merge($field_types, $image_field_type);
    return $field_types;

add_filter( 'xprofile_field_types', 'bpd_add_new_xprofile_field_type' );
  1. Tell XProfile  how to display an image field type on the admin screen:

Image Field Admin (Scanned Driver’s License)

function bpd_admin_render_new_xprofile_field_type($field, $echo = true){

        switch ( $field->type ) {
            case 'image':
                    <input type="file" name="<?php bp_the_profile_field_input_name() ?>" id="<?php bp_the_profile_field_input_name() ?>" value="" />
            default :
                    <p>Field type unrecognized</p>

        $output = ob_get_contents();

        echo $output;
        return $output;


add_filter( 'xprofile_admin_field', 'bpd_admin_render_new_xprofile_field_type' );
  1. Tell XProfile  how to display the image field on the user profile edit screen:

Image Field Edit (Scanned Driver’s License)

function bpd_edit_render_new_xprofile_field($echo = true){

    if(empty ($echo)){
        $echo = true;

        if ( bp_get_the_profile_field_type() == 'image' ){
            $imageFieldInputName = bp_get_the_profile_field_input_name();
            $image = WP_CONTENT_URL . bp_get_the_profile_field_edit_value();

                <label for="<?php bp_the_profile_field_input_name(); ?>"><?php bp_the_profile_field_name(); ?> <?php if ( bp_get_the_profile_field_is_required() ) : ?><?php _e( '(required)', 'buddypress' ); ?><?php endif; ?></label>
                <input type="file" name="<?php echo $imageFieldInputName; ?>" id="<?php echo $imageFieldInputName; ?>" value="" <?php if ( bp_get_the_profile_field_is_required() ) : ?>aria-required="true"<?php endif; ?>/>
                <img src="<?php echo $image; ?>" alt="<?php bp_the_profile_field_name(); ?>" />



        $output = ob_get_contents();

        echo $output;
        return $output;


add_action( 'bp_custom_profile_edit_fields', 'bpd_edit_render_new_xprofile_field' );
  1. This is an extremely critical hook function. Since XProfile  doesn’t have a provision for the adding of a new field type, it doesn’t give you a chance to render your field type. Normally this would mean having to edit core XProfile  code. Luckily, however, there’s a way out. By using the fact that bp_actions hooks are called before bp_screens, we can replace XProfile ‘s bp_screens hook with a custom one that shall render the custom field and then call XProfile ‘s bp_screens to proceed with the rest of the fields.
// Override default action hook in order to support images
function bpd_override_xprofile_screen_edit_profile(){
    $screen_edit_profile_priority = has_filter('bp_screens', 'xprofile_screen_edit_profile');

    if($screen_edit_profile_priority !== false){
        //Remove the default profile_edit handler
        remove_action( 'bp_screens', 'xprofile_screen_edit_profile', $screen_edit_profile_priority );

        //Install replalcement hook
        add_action( 'bp_screens', 'bpd_screen_edit_profile', $screen_edit_profile_priority );

add_action( 'bp_actions', 'bpd_override_xprofile_screen_edit_profile', 10 );
  1. Help XProfile  in saving the image field type data:
//Create profile_edit handler
function bpd_screen_edit_profile(){

    if ( isset( $_POST['field_ids'] ) ) {
        if(wp_verify_nonce( $_POST['_wpnonce'], 'bp_xprofile_edit' )){

            $posted_field_ids = explode( ',', $_POST['field_ids'] );

            $post_action_found = false;
            $post_action = '';
            if (isset($_POST['action'])){
                $post_action_found = true;
                $post_action = $_POST['action'];


            foreach ( (array)$posted_field_ids as $field_id ) {
                $field_name = 'field_' . $field_id;

                if ( isset( $_FILES[$field_name] ) ) {
                    require_once( ABSPATH . '/wp-admin/includes/file.php' );
                    $uploaded_file = $_FILES[$field_name]['tmp_name'];

                    // Filter the upload location
                    add_filter( 'upload_dir', 'bpd_profile_upload_dir', 10, 1 );

                    //ensure WP accepts the upload job
                    $_POST['action'] = 'wp_handle_upload';

                    $uploaded_file = wp_handle_upload( $_FILES[$field_name] );

                    $uploaded_file = str_replace(WP_CONTENT_URL, '', $uploaded_file['url']) ;

                    $_POST[$field_name] = $uploaded_file;


                $_POST['action'] = $post_action;



  1. Since you are most likely going to save the XProfile  images in a custom location, this is the function that tells WordPress what that location is:
function bpd_profile_upload_dir( $upload_dir ) {
    global $bp;

    $user_id = $bp->displayed_user->id;
    $profile_subdir = '/profiles/' . $user_id;

    $upload_dir['path'] = $upload_dir['basedir'] . $profile_subdir;
    $upload_dir['url'] = $upload_dir['baseurl'] . $profile_subdir;
    $upload_dir['subdir'] = $profile_subdir;

    return $upload_dir;
  1. The field type selection list still won’t display the image option since the recognized options have been hard coded into the XProfile  source code. This leaves browser-side intervention as the only way to add the image option. The following jQuery code should be added to a .js file which should be loaded by your theme’s functions.php. We’ll call the .js file xprofile-image.js.

Image Field Type


		//outerHTML method (http://stackoverflow.com/a/5259788/212076)
		jQ.fn.outerHTML = function() {
			$t = jQ(this);
			if( "outerHTML" in $t[0] ){
				return $t[0].outerHTML;
				var content = $t.wrap('<div></div>').parent().html();
				return content;

		bpd =

		init : function(){

				//add image field type on Add/Edit Xprofile field admin screen
			   if(jQ("div#poststuff select#fieldtype").html() !== null){

					if(jQ('div#poststuff select#fieldtype option[value="image"]').html() === null){
						var imageOption = '<option value="image">Image</option>';
						jQ("div#poststuff select#fieldtype").append(imageOption);

						var selectedOption = jQ("div#poststuff select#fieldtype").find("option:selected");
						if((selectedOption.length == 0) || (selectedOption.outerHTML().search(/selected/i) < 0)){
							var action = jQ("div#poststuff").parent().attr("action");

							if (action.search(/mode=edit_field/i) >= 0){
								jQ('div#poststuff select#fieldtype option[value="image"]').attr("selected", "selected");





  1. The following code (located in functions.php) loads xprofile-image.js:
function bpd_load_js() {
     wp_enqueue_script( 'bpd-js', get_bloginfo('stylesheet_directory') . '/js/xprofile-image.js',
							array( 'jquery' ), '1.0' );

add_action( 'wp_print_scripts', 'bpd_load_js' );

That’s it! You now have an image type XProfile  field.


UPDATE: 2014-04-03

There’s now a BuddyPress plugin available that eliminates the need for you to add the raw code into your BuddyPress-driven site.

  1. March 15, 2012 at 14:16

    hi, thanks for the great write-up.
    I’m trying this out, but I’, getting a problem when trying to add the new ‘image’ field type as a new profile field.
    I can see that the bpd_add_new_xprofile_field_type function is being called, as I’m doing a print_r of the array that it returns and I see the following:
    Array ( [0] => textbox [1] => textarea [2] => radio [3] => checkbox [4] => selectbox [5] => multiselectbox [6] => datebox [7] => image )

    However, in wp-admin, when I Add a new profile field, I don’t see and option for image.
    Any ideas what I might be doing wrong?
    thanks in advance 🙂

    • kalengi
      March 15, 2012 at 14:48

      Hi Bobaxford,

      My guess is that the problem lies in step 7 and 8 (the last two). The jQuery code (step 7) is the one that adds the new ‘Image’ option to the list. Confirm that the code is actually being loaded into your browser by placing an alert(); call inside the init function.

  2. April 2, 2012 at 23:25

    Thanks for the excellent write-up on XProfile. Your detail and explanations here go so far beyond the present information published in the WordPress and BuddyPress codex — giving an actual internal view on how the hooks are firing and how you can intervene with custom needs.

    I have a situation where I need to piggy back saving new database-sourced data into two hidden XProfile fields depending on the content of a visible field that the visitor is able to edit freely. This tutorial gives me a clear understanding on how to intercept the saving process so I can update these two hidden fields on the fly depending on the input of the accessible field upon a save.

    Thanks again, Alex!

    • kalengi
      April 3, 2012 at 00:38

      Hi Patrick,

      That was actually one of the aims of writing the tutorial. I realized the codex didn’t get much into how hooks actually interacted in a real application such as BuddyPress. It’s great that you’ve been able to apply this to a different problem. Thanks very much for the feedback 🙂

    • April 3, 2012 at 01:52

      thanks for the tip above about jQuery, that fixed it!

  3. iamryantaylor
    April 3, 2012 at 04:43

    Great Tutorial 🙂 I am getting a bit of issues with the upload directory. When ever I upload an image the source is http:///wp-content rather then the http:///wp-content/profiles//.

    Can you point me in the wright direction to get this working please?

    • iamryantaylor
      April 3, 2012 at 05:17

      I upload an image the source is url/wp-contentimg rather then the url/wp-content/profiles/userid/img.

      • kalengi
        April 3, 2012 at 11:03

        Hey Ryan,

        Sounds like your upload_path option is not set. You can confirm whether it is set by checking the value of $upload_dir['url'] in the function bpd_profile_upload_dir( $upload_dir ). It should show as url/wp-content/uploads in non-multisite installations. One quick way to set the option is to upload an image to one of your posts in WordPress. Once the image is uploaded, WordPress should have taken care of setting the option.

        A second issue here is that the bpd_profile_upload_dir( $upload_dir ) filter is most likely not being triggered. This would explain why /profiles/ is missing from the path. The /userid/ portion requires that the person editing the profile be the actual owner of the profile, and of course logged in :).

        Hope this helps and thanks!

        • iamryantaylor
          April 12, 2012 at 06:40

          Thanks kalengi for the reply. I have looked at the path and it seems fine but I think that the its deffiniately the bpd_profile_upload_dir ($upload_dir ) not being triggered.

          • kalengi
            April 12, 2012 at 10:28

            If the upload path filter is still not being triggered, try disabling your plugins one at a time to see which could be causing this. If it still doesn’t work then try using the default unmodified BuddyPress theme. If it still doesn’t work then you need to roll up your sleeves and dive into the world of single-stepping 🙂

          • kalengi
            May 3, 2012 at 19:15

            Hey Ryan,

            Check out the tip from Oscar. It’s probably the missing enctype that was stopping your code from working.

  4. April 12, 2012 at 13:23

    Very Impressive, A little debugging to do but overly appreciative!

    • kalengi
      April 12, 2012 at 17:21


  5. Ashiq
    April 23, 2012 at 06:50

    At first thanks a lot for this wonderful hack. However, I am having a problem. I have followed your instruction. And now I have a Picture Upload field at registration. But the problem is, when user register for a new account, and select a new Picture by browsing and click Sign Up, nothing happens, and it again loads the Register page.

    • kalengi
      April 23, 2012 at 13:37

      Hi Ashiq,

      Does the registration work without the picture field? We need to narrow down and see whether the issue is specifically related to the picture field.

      • Ashiq
        April 25, 2012 at 05:05

        Hi Kalengi,
        Yes, Registration works without picture field. With default Buddypress Registration form.

        • kalengi
          April 25, 2012 at 12:57

          Then I think the issue is that since you’re registering a new user, there’s no user_id to match the uploaded photo. The code works on condition that the person uploading the photo is logged in.

  6. Sabrina
    April 26, 2012 at 21:17


    I’ve been trying it but i dont get it 😦 in step 2 you have to see the options image right? i don’t see anything 😦 It should be in the functions.php of the theme right?

    • kalengi
      April 26, 2012 at 21:39

      Hi Sabrina,

      Yes, in step 2 you should see a field like the one labeled “Scanned Driver’s License (Required)”. Could you describe the steps you’re going through so that I can perhaps determine what may be the issue?

      Also correct, that the code should go into the theme’s functions.php.

      • Sabrina
        April 26, 2012 at 21:46


        I just copied the text of step 1 and 2 in my functions.php file.

        • kalengi
          April 26, 2012 at 21:59

          Are other fields showing up? Is the active theme a child theme of bp-default? Where’s the location of the functions.php? The last two questions can indicate whether functions.php is being executed at all.

          • Sabrina
            April 26, 2012 at 22:17

            i’ve made my own theme..

            it is located in : wp-content/themes

            the standard fields are showing up.

          • kalengi
            April 26, 2012 at 22:25

            Looks like we’re both online… Could you send me your skype id via the contact form so we see what’s up.

    • Ashiq
      April 27, 2012 at 15:41

      What do you mean by, The code works on condition that the person uploading the photo is logged in? I thought, that the person is uploading photo during registration?

      • kalengi
        April 28, 2012 at 18:57

        The reason why you need to add the photo after the user has registered is that the user_id is used in naming the folder to hold the photo. If you wish to add the photo as part of the registration process, then you need to change how the photo folder is named so it no longer needs a user_id.

  7. Sabrina
    April 27, 2012 at 17:11

    it’s already working.. i thought it had to show in step 2, but the picture is the final step 😛

    • kalengi
      April 28, 2012 at 18:57

      Exactly! You need to ge through all the steps before anything is viewable.

  8. April 29, 2012 at 07:46

    Hi !

    I have implemented it on the default theme of the wordpress and some of the themes of wordpress.org but it is not working at anyone of them .

    I have follow the all steps I have copied all the functions into the functions.php except the step 7 as it have to be in the .js file.

    Can you please tell me that why it is not working,

    Thankyou !

    • kalengi
      April 29, 2012 at 13:01

      Hi Haseeb,

      All the steps have to be done before you can see the results. Step 7 is important in order to avail the ‘Image’ option for the Field Type drop-down.

  9. April 29, 2012 at 14:00

    I have solved that but it is not storing picture anywhere i have tried in the edit profile options as well as registered and have created profiles folder and gave them 777 permissions in wp-content as well as uploads folder. Nut got nill result. Can you check it please and give me a solution.

    • kalengi
      April 29, 2012 at 14:21

      Have you confirmed that the code is targeting the right folder? It could be saving to a different location based on your upload_path setting in the options table. I’m not able to check for you at this time, but if you send me a message via the contact form we can arrange a time.

      • April 29, 2012 at 15:08

        Yes i have confirmed that the path is set default by wordpress. and it is ok can you tell me please solution

  10. May 3, 2012 at 18:33


    Since the $_FILES didn’t go through because of missing enctype in the form, I got around it by adding:
    jQ(“#profile-edit-form”).attr(“enctype”, “multipart/form-data”);
    in the JS file

    Hope it helps somebody.
    Oscar Frowijn
    Ozkaa Technologies

    • kalengi
      May 3, 2012 at 19:09

      Hi Oscar,

      That’s perfect! I had missed it in the original post since in my case I customized the edit page in a child theme so the enctype was taken care of. Your solution allows the site creator to avoid having to customize an edit file if the enctype is the only thing missing.

      Thanks! 🙂

    • John
      May 5, 2012 at 04:00

      Where in the js do you add that?

      • ozkaatechnologies
        May 5, 2012 at 16:39

        @John, Anywhere in the js file, as long as its not in the function scope.
        so, just put all the way at the bottom, and you’ll be fine.
        Use firebug to select the form and see if the enctype was added to the form element.

        @Kalengi, thanks!

  11. saschapaukner
    May 6, 2012 at 01:50

    Wow, this would be absolutely amazing to get to work! Thanks very much for this explicit write-up! Wish an image field would become BP core…

    • kalengi
      May 6, 2012 at 05:28

      Hi Sascha,

      I absolutely agree. An image field should be part of BP Core. Thanks very much! 🙂

  12. sabrina
    May 7, 2012 at 17:55


    How can i put instead of a image field a field for uploading a file such as a PDF?

  13. John
    May 11, 2012 at 07:11

    I’m really stuck similar to iamryan was. images don’t appear to be getting saved. and the saved link points to /wp-contentimage.jpg. i need some suggestions

    • kalengi
      May 13, 2012 at 18:29

      Hi John,

      Comment out this line: add_filter( 'upload_dir', 'bpd_profile_upload_dir', 10, 1 ); and see whether it works.

      • Sabrina
        May 13, 2012 at 20:38


        this is seems to work ( i see the files in the upload directory), but if i click on it then it doesn’t show up..

        • kalengi
          May 14, 2012 at 16:00

          Hi Sabrina,

          This could indicate a problem with the creation of the link. What does the link look like?

      • John
        May 14, 2012 at 01:55

        this doesn’t appear to create any change.

        • kalengi
          May 14, 2012 at 15:58

          Alright. Try creating a user profile and also upload a new avatar. Then check where BuddyPress saves the avatar. That should at least indicate that the WP uploads folder is correctly setup. Without the line of code that I asked you to comment, the image you’re trying to upload should show up in the default WP uploads folder.

  14. mike
    May 19, 2012 at 19:04

    i cant get the file to save anywhere…

    i tried the comment out trick….

    still cant see the file saving anywhere on my site…not a permissions problem because im on a localhost

    • kalengi
      May 20, 2012 at 01:11

      Hi Mike,

      Have you confirmed that:
      1. BuddyPress is saving user avatars to the uploads folder
      2. The profile fields form has the correct enctype (multipart/form-data).

      • mike
        May 20, 2012 at 03:38

        that was the charm!!!! thank you enctype!

      • mike
        May 20, 2012 at 04:02

        Do you think there is a way we can add a default value of the previous entry to the field?

        i ask because…i added more options in the edit group

        and whenever some other option is filled but the image field is left untouched…it simply saves as a blank entry

        • kalengi
          May 20, 2012 at 04:28

          You could edit the function bpd_edit_render_new_xprofile_field() to generate a hidden input holding the value of bp_get_the_profile_field_edit_value(). Then when saving in bpd_screen_edit_profile() you use the value of the hidden input if there’s no uploaded image.

          • Lucas Tito
            July 30, 2012 at 15:27

            I’m a total php nooby :/ could you maybe post what you where you changed and added stuff, so i can copy paste maybe :3

  15. mike
    May 20, 2012 at 05:19

    ok i added the hidden field and it is confirmed to have the value of the saved image

    so then in my functions file i tried this statement

    if($_FILES[$field_name]) {
    $uploaded_file = $_FILES[$field_name][‘tmp_name’];
    $uploaded_file = $_POST[‘savedbackground’];

    right above the add filter line that changes the directory

    it didnt work but im too dumb to see where i messed up

    • kalengi
      May 20, 2012 at 13:53

      This is how I’d go about this:

      1. Have a known naming pattern for the hidden inputs eg. 'field_' . $field_id . 'hidden'
      2. Put an else clause for if ( isset( $_FILES[$field_name] ) ) {:

                  $field_name_hidden = 'field_' . $field_id . 'hidden';
                  if ( isset( $_POST[$field_name_hidden] ) ) {
                      $_POST[$field_name] = $_POST[$field_name_hidden];
  16. May 31, 2012 at 22:49

    Wow, I have been looking for something like this. This will give us a huge jump start on getting it implemented.


    • kalengi
      June 1, 2012 at 16:23

      Thanks Eric!

  17. June 21, 2012 at 21:00


    This tutorial is awesome. Thank you.

    I can save an image, and it shows up on the edit page. On the public profile tab, though, a link displays instead of an image. For example: /uploads/2012/06/american_blk_lab.jpeg.

    The working image URL is http://mysite.com/site/wp-content/uploads/2012/06/american_blk_lab.jpeg.

    Any ideas on how to fix the public display?

    • kalengi
      June 22, 2012 at 10:48

      Hi Sam,

      If you look at the code in step 3. (Tell XProfile how to display the image field…) you see that in order to display the image you need to have an img tag and supply the image url as the src attribute. Also since the saving functionn does not save the whole url, you have to complete it by prepending WP_CONTENT_URL.

      • June 23, 2012 at 04:43

        That function—bpd_edit_render_new_xprofile_field()—seems to be working. When I edit and save my profile, the image displays correctly in Profile » Edit. When I navigate to Profile » Public, however, only a broken link displays. Does bpd_edit_render_new_xprofile_field() affect the display on Profile » Public?

        • kalengi
          June 23, 2012 at 13:27

          The functionn only applies to editing. The public display portion is not handled by that code. In my previous reply I was pointing you to the bits of code that can be placed in your profile display page so it can show the image. Alternatively, you could remove this code $uploaded_file = str_replace(WP_CONTENT_URL, '', $uploaded_file['url']) ; from the function bpd_screen_edit_profile(). That allows it to save the whole image url. Once you do that then you’ll also need to change $image = WP_CONTENT_URL . bp_get_the_profile_field_edit_value(); to $image = bp_get_the_profile_field_edit_value(); in the function bpd_edit_render_new_xprofile_field

          • kalengi
            June 29, 2012 at 08:55

            Hi Sam,

            There’s a bit of an error in the code tweaks I described. When you remove $uploaded_file = str_replace(WP_CONTENT_URL, '', $uploaded_file['url']) ; you should then put this in it’s place: $uploaded_file = $uploaded_file['url'] ;.

  18. June 24, 2012 at 20:28

    This is very useful, thanks a lot!

    Do you have any idea about how to validate a custom field? I’ve been playing around with the ‘xprofile_data_is_valid_field’ hook, but it doesn’t seem to work. Many thanks in advance!

    • kalengi
      June 24, 2012 at 22:08

      Hi Voles,

      That hook verifies whether the field being saved actually exists. The hook you’re looking for is xprofile_data_before_save which you can use to examine the data before it is saved.

  19. omdev
    June 26, 2012 at 10:21

    i am getting error at

    function(jQ){ sysntex error please give me suggestion i really nee it

    • kalengi
      June 26, 2012 at 11:43

      Hi omdev,

      Two things come to mind:
      1. Check that you’ve copied the js code exactly as it is in the article and that there’s no other code in the js file.
      2. If you still get an error, paste the exact error message here so I can have a better idea what’s up

  20. Lucas Tito
    July 24, 2012 at 16:54

    Hey after following your tutorial what should i do to add more image fields ?
    Is it possible to have up to 6 ? Not so much php expierence :/ i’d be happy to get some tips.
    Great Tutorial btw. Thanks in advance!

    • kalengi
      July 24, 2012 at 17:58

      Hi Lucas,

      Once the code is in place you can add as many image fields as you wish to a user profile. The code allows BuddyPress to recognize the new type of field and how to handle it.

      • Lucas Tito
        July 25, 2012 at 15:59

        thats gorgeous! thank you for your quick answer.

  21. Lucas Tito
    July 26, 2012 at 16:25

    Hey there again,
    i get several errors 😦 These are permanently on every dashboard page but im still able to navigate and edit stuff:
    Warning: Cannot modify header information – headers already sent by (output started at /vrmd/homepages/u51488/wp-content/themes/custom-community/functions.php:576) in /vrmd/homepages/u51488/wp-includes/option.php on line 563
    Warning: Cannot modify header information – headers already sent by (output started at /vrmd/homepages/u51488/wp-content/themes/custom-community/functions.php:576) in /vrmd/homepages/u51488/wp-includes/option.php on line 564

    563 & 564 from option.php:
    setcookie( ‘wp-settings-‘ . $user->ID, $settings, time() + 31536000, SITECOOKIEPATH );
    setcookie( ‘wp-settings-time-‘ . $user->ID, time(), time() + 31536000, SITECOOKIEPATH );

    on members/agentur/profile/edit/ page i get this without any html rendering:
    Warning: Cannot modify header information – headers already sent by (output started at /vrmd/homepages/u51488/wp-content/themes/custom-community/functions.php:576) in /vrmd/homepages/u51488/wp-includes/pluggable.php on line 881

    881 from pluggable:
    header(“Location: $location”, true, $status);
    (part of a wp_redirect function)

    Errors are pointing to 576 of function.php which is actually the php opening bracket of Tutorial Step 1.

    Actually im able to add an image field to via extended profile fields screen though.
    I’d be happy about any tips because this is a very important function for me :/

    Thank you!

  22. Lucas Tito
    July 27, 2012 at 12:13

    actually nothing but php brackets and spaces but the preceding function is:

    //modify the query string with the search term
    function cc_global_search_qs(){

    return “search_terms=”.$_REQUEST[‘search-terms’];

    function cc_is_advance_search(){
    global $bp;
    if($bp->current_component == BP_SEARCH_SLUG)
    return true;
    return false;
    remove_action( ‘bp_init’, ‘bp_core_action_search_site’, 7 );


    • kalengi
      July 27, 2012 at 14:02

      That’s exactly what i suspected 🙂 Remove all those php brackets and spaces. Refering to the file you sent, remove everything between 573 and 578.

      • Lucas Tito
        July 27, 2012 at 18:25

        Yes that solved it 🙂 After experiencing upload dir errors solved by hardcoding enctype to edit.php (js trick didnt work :P) i got a totally different disaster now. Hope i don’t get annoying! I added 2 Image Fields via Extended Profile Field Backend and i can upload a Picture that actually shows but only one so if i try to add the next the first uploaded disappears oO. Would be so thankful for a fix of this “final” Problem 😀

  23. August 19, 2012 at 02:41

    error in step 7): appears that: Parse error: syntax error, unexpected T_FUNCTION in /home/portallo/public_html/wp/wp-content/themes/bp_theme/functions.php on line 988

    and line 988 is: function(jQ){

    how do I fix it?

  24. August 24, 2012 at 10:55

    Nice post. but better if someone can build a plugin for image field.

    • kalengi
      August 24, 2012 at 11:00


  25. kruspexkrusoex
    September 4, 2012 at 12:20


    We have been looking for to do this and your tutorial has benn very very very helpfull for us. It’s working for adding a background image to de members header 😀


    • kalengi
      September 4, 2012 at 13:20

      Great to know you found it useful 🙂

  26. October 3, 2012 at 14:58

    Hi! THis is really useful – could it be extended for other types of document especially .doc and .pdf ??

    • kalengi
      October 3, 2012 at 17:40

      Hello Togethernet,

      The technique applies to those other content types as well. Just a few tweaks in the code so it handles the documents correctly.

      • October 3, 2012 at 19:42

        Terriffic – would you care to point out where those tweaks are? This weould be even more terriffic if you turned it into a plug-in. I’d buy it.

        • kalengi
          October 4, 2012 at 13:39

          I’d love to do a plugin, but I’ve been so busy lately it’s unlikely I’ll find a moment any time soon. As for where to tweak, I have to examine the code some, but off the top of my head, you would at a minimum need to replace any img tag with a link to the document.

  27. October 6, 2012 at 15:41

    Hi, This what I am searching for last weeks, I am not coder, and thats my problem to make it work 🙂

    I put all codes on theme function.php
    I made js/xprofile-image.js in theme’s directory

    my results:
    I have image add option in profile field
    I have browse option in my profile-edit

    but whenever I upload image I have a link in profile area with this url

    am ı puting js file in wrong place, couse whenever i delete it nothing changes.

    hope someone can help. I can share my screen with join-me.

    • kalengi
      October 7, 2012 at 23:22

      Hi Boun,

      Have you confirmed that the images are actually saved to the server? Secondly, the code in the article does not cover how to display the image on the profile page. For that you need to add an img tag and give it the image url. Check through the comments for possible issues to look out for.

  28. ilitullx
    October 24, 2012 at 08:51

    hi! wondering if there would be a simple way to make the images display as thumbnails instead of the whole images? Love this tutorial and the rest of these comments threads have been really useful too!

    • kalengi
      October 24, 2012 at 13:59

      Hello Ilitullx,

      You can use the image_resize function to create thumbnails when an image has been uploaded.

  29. October 27, 2012 at 23:11

    Thanks. Add custom image user field Works fine direct with Buddypress 6.x and a lot of plugins. The jQuery fix to the profile edit form needed. And ;

    This is how a nice turtorial is for me, to examinate the parts so you actually learning and can develope from that. A very old thread still going strong!

    / We don need plugins for everything, Thanks again.

    • kalengi
      October 28, 2012 at 15:42

      Hey Jonas,

      Great that you found this helpful and good to know it still works in BP 6.x 🙂

  30. Pete
    November 29, 2012 at 23:53


    This is exactly what I need but I’m really struggling to get it working. I have been through everything in the thread but having no luck. I have a functions.php and the js file a child bp theme. I can create image fields no problem but no images are uploading to the server (I can upload avatars) and on the profile page I get the following link from the image name that appears:


    Its not a permissions thing and not sure where to go next. I have the jQuery fix in place but doesn’t change the outcome with or without. I have all other plugins disabled, clean install of BP. Hoping it’s something really obvious I’m missing!

    Any help on this would be really appreciated! Thanks!

    • kalengi
      November 30, 2012 at 11:30

      Hi Pete,

      Get in touch via the contact form so you can share the code and I see what’s missing.

  31. Rick
    December 2, 2012 at 05:56

    I’ve gone through the steps but when I’m in wp admin, the form to add the image doesn’t show up? Any clue what could be up? Thanks!

    • kalengi
      December 3, 2012 at 00:31

      Hi Rick,

      The image field is supposed to show up on the same form as the other profile fields. If it’s not showing up then it wasn’t added to the profile fields, so add it via the same process that you used to create the other fields, only this time specify that it’s ‘image’ type.

      • Rick
        December 6, 2012 at 05:57

        Thanks for the response. I worked out the issue. And thanks for Oscar’s JS encoding bug fix — that set my upload issue straight…. perhaps you should add that snippet into your sample code?

  32. Sheheryar
    December 5, 2012 at 13:31

    The image is not saving in the server. Please help me out.
    How to save in wp-content/upload/ directory.
    I have tried the solutions mentioned above but no use.

    • kalengi
      December 5, 2012 at 14:56

      Hi Sheheryar,

      Check folder permissions – are you able to upload profile avatars for instance. Check the form enctype to ensure it supports file upload. Confirm that there are no javascript errors in the browser. If all these are ok then the image should upload ok.

      • Sheheryar
        December 5, 2012 at 15:27

        Yes I can upload profile avatars and there is no error.

        • kalengi
          December 5, 2012 at 19:00

          Have you confirmed the enctype and absence of javascript errors?

  33. December 16, 2012 at 23:14

    Hi there
    I still cannot use this steps because of my low knowledge of codding.
    I find this plugin that adds picture to profile but in different tabs.. can be a good help for people who considering making plugin for this article 🙂


    • kalengi
      December 17, 2012 at 12:18

      Thanks very much for the link!

  34. Pete
    January 9, 2013 at 16:58

    I upgraded to WordPress 3.5, buddypress 1.6.2, and I’m now unable to add new image profile fields. I can still use the ones previously created but if I go to add a new one that type doesn’t display in the list. This means I can’t edit them either.
    Have you seen this happen?
    Thanks again!

    • kalengi
      January 9, 2013 at 22:12

      Hi Pete,

      Haven’t tried it out with those parameters. When I get a moment I’ll setup a similar environment to check whether it works.

      • February 19, 2013 at 23:09

        Hi Kalengi,

        First of all thank you for the time and effort you’ve put in creating this clear tutorial step by step!

        Unfortunately I can’t get it to work with my install just as Pete. I’m using Version 3.5.1 WP and Version 1.6.4 BP.

        I’ve placed the code exactly as you say in the tutorial above, the javascript file is called correctly (checked it with an alert function) but just as Pete says the image field isn’t visible in the dropdown box in the backend.

        Are there any updates?

        Thanks in advance!!

        gr Victor

        • kalengi
          February 20, 2013 at 13:37

          Hi Victor,

          Unfortunately I haven’t yet gotten round to testing the new environment. I will try and steal a moment in the next few days to see what’s up. Have you done any customization to your BP installation?

          • February 21, 2013 at 23:19

            Hi Kalengi,

            Thanks for the quick reply! That would be very kind..
            The only thing i’ve added in functions.php was a script so that buddypress can regconize youtube links and convert them to embed movies. The following script is added:

            function bp_embed_in_profile() {
            add_filter( ‘bp_get_the_profile_field_value’, ‘bp_enable_embed_in_profile’, 9, 3 );
            add_action( ‘bp_init’, ‘bp_embed_in_profile’, 0 );

            function bp_enable_embed_in_profile( $val, $type, $key ) {

            $field = new BP_XProfile_Field( $key );
            $field_name = $field->name;

            $provider = array( ‘youtube’, ‘vimeo’, ‘instagram’, ‘bliptv’, ‘twitter’);

            if( strtolower( $field_name ) == in_array( strtolower( $field_name ) , $provider ) ) {
            $val = strip_tags( $val );
            return wp_oembed_get( $val, array( ‘width’ => 400 ) );
            return $val;

            you can view the website on http://www.solidgroundmovement.nl/beta

            Looking forward to your reply!

            gr Victor

  35. TF
    January 11, 2013 at 17:57

    Hi There, great tutorial, but I don’t get the code work. After adding the second part of code I get a white screen an d that remains like that until the full code is added. I run a child theme.

    Your help would be very much appreciated. Thanks!

    • TF
      January 11, 2013 at 18:29

      OK, got the code and .js into the right place but don’t see anything in the profile field settings.

      • kalengi
        January 12, 2013 at 01:04

        Hello TF,

        I’m not sure where exactly you’re stuck. Also, you have to put in all the code before you gwt any results.

  36. Sajin
    January 25, 2013 at 19:40


    bpd_profile_upload_dir() is not triggered. can anyone help me

    • kalengi
      January 25, 2013 at 22:40

      Hi Sajin,

      That function is triggered by the code: add_filter( 'upload_dir', 'bpd_profile_upload_dir', 10, 1 );. If it isn’t executing then it means the code is not being reached. Which would suggest that this test is failing: if ( isset( $_FILES[$field_name] ) ) {

  37. arfpogi
    March 8, 2013 at 08:30

    I’ve been trying it but i dont get it in step 2 you have to see the options image right? i don’t see anything It should be in the functions.php of the theme right?. .

    OR here
    buddypress plugin

    or here


    thanks in advance. .

    • kalengi
      March 8, 2013 at 18:26

      Hello Arfpogi,

      The effects are not observable until all the steps are complete. The screenshots just show what parts of BuddyPress are changed by the code.

  38. arfpogi
    March 8, 2013 at 19:37

    hi kalengi. . thanks for your reply. . in step7 (added to a .js file which should be loaded by your theme’s functions.php) ??

    • arfpogi
      March 8, 2013 at 20:05

      hi ..kalengi . . it already done. . thanks for this thread. . thanks again!

  39. March 19, 2013 at 10:03

    Please help me how to upload this steps

  40. March 19, 2013 at 16:35

    Please help me Kalengi. the code is not working in my case…..

    This code written in functions.php

    function bpd_add_new_xprofile_field_type($field_types){
    $image_field_type = array(‘image’);
    $field_types = array_merge($field_types, $image_field_type);
    return $field_types;

    add_filter( ‘xprofile_field_types’, ‘bpd_add_new_xprofile_field_type’ );

    // Tut Step 2
    function bpd_admin_render_new_xprofile_field_type($field, $echo = true){

    switch ( $field->type ) {
    case ‘image’:
    <input type="file" name="” id=”” value=”” />

    Field type unrecognized

    <label for="”>
    <input type="file" name="” id=”” value=”” aria-required=”true”/>
    <img src="” alt=”” />

    $profile_subdir = ‘/profiles/’ . $user_id;

    $upload_dir[‘path’] = $upload_dir[‘basedir’] . $profile_subdir;
    $upload_dir[‘url’] = $upload_dir[‘baseurl’] . $profile_subdir;
    $upload_dir[‘subdir’] = $profile_subdir;

    return $upload_dir;

    //Tut Step 7 – Load .js

    function bpd_load_js() {
    wp_enqueue_script( ‘bpd-js’, get_bloginfo(‘stylesheet_directory’) . ‘/js/xprofile-image.js’,
    array( ‘jquery’ ), ‘1.0’ );

    add_action( ‘wp_print_scripts’, ‘bpd_load_js’ );

    But result show “Remote server or file not found”
    Why i am getting this error..

    • kalengi
      March 21, 2013 at 18:43

      Hi Baldev,

      Check for the following:

      1. That you have put in all the code. Some steps are missing from the code that you pasted.

      2. That the file /plugins/buddypress/bp-themes/bp-default/js/xprofile-image.js exists and contains the js code from step 7

  41. May 20, 2013 at 15:42

    I’ve succesfully installed this code. Thanks a lot! I noticed that when adding two such images to my profile and I tried to edit one, the first one would disappear again.

    I eventually fixed this by creating a hidden input with the same name+”_hidden”. And then add a check on
    if ($_FILES[$field_name][‘error’] == 4)
    $_POST[$field_name] = $_POST[$field_name.’_hidden’];
    // upload

    • kalengi
      May 20, 2013 at 15:58

      Hi Rein,

      Thanks very much for the fix! Which version of WordPress/BuddyPress did you use?

  42. July 16, 2013 at 07:23

    Hey kalengi, I noticed this code doesn’t work with the latest version of WordPress & BuddyPress. Can you update this week? Thanks 🙂

    • September 2, 2013 at 17:00

      Thanks CodeATheme for your reply, i spent one hour to debbuging, i see the alert but i don’t see de image option in the list 😦 please tweet me if you find a solution 🙂

  43. November 27, 2013 at 17:01

    Hi kalengi.

    It seems the “bpd_edit_render_new_xprofile_field” doesn’t get called at all for fields with type “image”, so it never reaches the if ( bp_get_the_profile_field_type() == 'image' ){

    If I change the field type to anything else other than image, the “bpd_edit_render_new_xprofile_field” is being called, otherwise it skips it out.

    I assume this is to do with an update to Buddypress/Wordpress.

    Any ideas?

    • kalengi
      November 28, 2013 at 03:21

      Hello Ben,

      I believe that could be the case. I did a quick check of the changes that came in with the new versions of BuddyPress/WordPress and realized it required a bit more time than I had on my hands to work out a fix. If you find one before I do, please post the solution here for others that have been looking.

  44. March 10, 2014 at 10:54

    Anyone made this code work on the latest WP 3.8.1 and BP 1.9.2 ?

    • kalengi
      March 10, 2014 at 13:49

      Hi Oscar,

      I’ve checked it out under those conditions and it still works.

      • March 10, 2014 at 14:18

        Thnx for your reply Kalengi
        But I couldnt make it work. I cant see any extra fields on admin user fields. I have child theme, so where you save the .js file? and where is your profile image folder?

        • kalengi
          March 11, 2014 at 04:15

          The js file goes to a sub-directory called js in your child theme directory.

          The normal WordPress upload directory is /wp-content/uploads. The images are saved into the /wp-content/uploads/profiles sub-directory.

  45. August 12, 2015 at 14:36

    Hi Kalengi,

    I have been using your plugin BuddyPress XProfile Image Field for some time. And it was working fine. But suddenly now I am getting error when I am adding a field as an image that “The profile field type image is not registered.” Can you guide me on this? I am a novice with buddypress. The plugin was working great on the same site on which I am getting this error now. Can it be anything to do with latest wordpress update? I have recently updated wordpress on that site to 4.2.4.

    Thank you in advance.

    • KalenGi
      August 18, 2015 at 16:01


      This is most likely a compatibility issue with the latest WordPress. I shall run a test on it this week and let you know what I come up with.

      Thanks for using the plugin!


    • KalenGi
      September 11, 2015 at 10:09

      The issue was related to a change in BuddyPress way of handling XProfile fields. I have sorted this out and the latest version of the plugin works well on WordPress 4.3 with BuddyPress 2.3.3

      • sjaeiou
        July 30, 2018 at 18:30

        Hi, I met the same issue which says “The profile field type image is not registered.”. I’m trying to copy all of the code in this article and do some changes to add my custom field in xprofile. Do you have a plan to update this article? Thanks!

  1. September 20, 2012 at 00:36
  2. March 12, 2014 at 16:33

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: