Skip to:
Content
Pages
Categories
Search
Top
Bottom

Adding profile fields to members directory

  • @antipole

    Participant

    Hi… I have a BP site with members’ directory here.

    I would much like to add to this directory list certain extra profile fields (not to the individual member’s entry).

    I have searched for a plugin without luck. I could attempt simple php mods if pointed in the right direction. I found this but it is some years old and I am not sure if it is the best place to start.

    Any help much appreciated.

    WordPress 4.3.1; BuddyPress 2.3.4; bbPress 2.5.8

Viewing 16 replies - 1 through 16 (of 16 total)
  • @henrywright

    Moderator

    There’s 2 ways of doing this.

    1. You could modify the members-loop template (see the BuddyPress Template Hierarchy for details on how that’s done). See here. You would just add bp_member_profile_data( 'field=the field name here' ); to the template.

    2. Add this to your theme’s functions.php file:

    function add_info_to_members_loop() {
        echo bp_get_member_profile_data( 'field=the field name here' );
    }
    add_action( 'bp_directory_members_item', 'add_info_to_members_loop' );

    @antipole

    Participant

    Thank you, thank you for your clear and authoritative reply.

    I adopted method (2) as it seemed easier for me and I now have the result I wanted.

    Very happy!
    Tony

    @henrywright

    Moderator

    Great to hear 🙂

    Very cool yacht by the way! I’m going to visit my uncle’s this Thursday. It’s moored at Canvey Island while he does some restorations.

    @antipole

    Participant

    So I am getting my extra user data fields with a line like:
    echo '<div style="position: absolute; left:150px;">' , bp_get_member_profile_data('field=Ovni model'),'</div>';
    But I would like them to be search links as it is in an individual profile. I have achieved this with

    echo '<div style="position: absolute; left:60px;"><a href=', $bp->pages->members, '?s=', bp_get_member_profile_data('field=Ovni model'),' rel="nofollow">' , bp_get_member_profile_data('field=Ovni model'),'</a></div>';
    

    However, I am now also using the plugin Custom Profile Filters for BuddyPress, which lets me set which profile fields should not be search links and also allows users to spilt their data up, so a profile field “[ocean] and [coast]” gets two separate search links, one for ‘ocean’ and another for ‘coast’. Neat. It seems to do this by adding a filter to bp_get_the_profile_field_value.

    However, my manual addition of search links as above ignores these settings, and any [] in the fields comes through and are visible.

    It occurs to me that, rather than fetching the fields with bp_get_member_profile_data(), I would do better to get the data however it is got for the individual profile display, as this method puts the search links in and obeys the options set in Custom Profile Filters for BuddyPress. I have spent much of today trying to find how to call bp_get_the_profile_field_value. If I use
    echo '<div style="position: absolute; left:150px;">' , bp_get_member_profile_value('field=Ovni model'),'</div>';
    I get an invalid link. I suspect it need a data type argument to get a search link. I have tried to find how it is called to display the user profile, but failed to find it. In the BP Codex I have only found how to remove the filter that puts the links in.

    If someone could enlighten me it would be most helpful. Thanks.

    @danbp

    Participant

    Hi @antipole,

    try this:

    function my_custom_clickable_directory_profile_field() {	
    
    if ( $value = xprofile_get_field_data( 'Ovni model', bp_get_member_user_id() ) ) :
    
       // as of xprofile_filter_link_profile_data function
       $search_url = add_query_arg( array( 's' => urlencode( $value ) ), bp_get_members_directory_permalink() );
       $clickable = '<div class="click_dir"><a href="' . esc_url( $search_url ) . '" rel="nofollow">' . $value . '</a></div>';
    	
       echo $clickable;
    	
       endif;
    }
    add_filter ( 'bp_directory_members_item', 'my_custom_clickable_directory_profile_field' ); 

    @antipole

    Participant

    @danbo… thank you for responding. I am struggling – I am not an expert in this and I am unsure what is called by what, and whether the filter you suggest will be invoked by what I had already. I now have your suggestion included:

    function add_info_to_members_loop() {
    	echo '<div style="position: absolute; left:60px;">', bp_get_member_profile_data('field=Ovni model'),'</div>';
    	echo '<div style="position: absolute; left:100px;">', bp_get_member_profile_data('field=Rig'),'</div>';
    }
    add_action( 'bp_directory_members_item', 'add_info_to_members_loop' );
    
    function make_directory_profile_field_searchable() {	
    	if ( $value = xprofile_get_field_data('Ovni model', bp_get_member_user_id() ) ) :
    	   // as of xprofile_filter_link_profile_data function
     	  $search_url = add_query_arg( array( 's' => urlencode( $value ) ), bp_get_members_directory_permalink() );
    	   $clickable = '<div class="click_dir"><a href="' . esc_url( $search_url ) . '" rel="nofollow">' . $value . '</a></div>';	
    	   echo $clickable;	
    	   endif;
    }
    add_filter ( 'bp_directory_members_item', 'make_directory_profile_field_searchable' ); 	 

    Your code has the field name ‘Ovni model’ built in and I don’t understand how to pass the field name through from add_info_to_members_loop.

    [I still think that if I could work out what is called when a field is displayed in the user profile, that call would deliver what I need in the members loop.]

    I have spent a long while trying to fathom this out, so extra help will be really appreciated.

    @danbp

    Participant

    Hi @antipole,

    from non-epert to non-expert, i’ll try to explain what i understood from your previous request…

    You want to show a profile filed value on the member directory and this value should be searcheable in the same way as on a profile. Right ?

    On members directory, we need a field name, a field value, a user ID and a search link.

    This line of code will fetch the correct field, associated to the user ID:
    $value = xprofile_get_field_data('Ovni model', bp_get_member_user_id() ) )

    This line will build the url for that value
    $search_url = add_query_arg( array( 's' => urlencode( $value ) ), bp_get_members_directory_permalink() );

    And this line will build the output. I use a div with a class name. I recommand you keep it as is and add your custom style from within your child-theme style.css. Inline style is not necessary here.
    $clickable = '<div class="click_dir"><a href="' . esc_url( $search_url ) . '" rel="nofollow">' . $value . '</a></div>';

    And this generate the output: echo $clickable;

    And finally, we add our custom filter to the existing by using add_fliter( $filter_name, $my_filter):
    add_filter ( 'bp_directory_members_item', 'make_directory_profile_field_searchable' );

    That’s it.

    My snippet let you add such a clickable field. The field name is “ovni model”.
    The code is first calling that field, and before the final output on members directory, we add a clickable search url. This is a strictly BP way to add an url to a (field)value. This snippet doesn’t need another function to work.

    The field, from a profile perspective, will be Name Ovni model: value flying saucer. The link structure will be your-site/members/username/?s=flying_saucer.

    The snippet use the same structure on members directory and you’ll get the same result.
    Guess you don’t need the additionnal function add_info_to_members_loop.

    Try first and struggle after, it’s better for your karma ! 😉

    @antipole

    Participant

    Thank you to all who have helped and especially @danbp who took time to explain things at length.
    I have finally grasped how this thing works, more or less.

    I do need to apply the same quite complex filter to both the profile and directory list. I have now devised a common filter function plugin that can be invoked within the members loop as a filter and within the profile display as an action. I have to call it in different ways, depending on where it is being called from, and the trick was to call it from two separate hookable functions. The core of what I have follows:

    
    // Remove standard filtering of profile fields
    function ovni_init() {
    	remove_filter( 'bp_get_the_profile_field_value', 'xprofile_filter_link_profile_data', 9, 2 );
    	}
    add_action( 'bp_init', 'ovni_init' );
    
    // add our replacement filter, which is given a field value, to the members loop
    function ovni_filter_field_for_directory($field_value){
    	$field_name=bp_get_the_profile_field_name();
    	return ovni_get_field_searchable($field_name);
    	}
    add_filter( 'bp_get_the_profile_field_value', 'ovni_filter_field_for_directory', 50, 1 );
    
    // add fields to directory listing make them searchable according to rules of this plugin
    function ovni_add_info_to_members_loop() {
    	echo '<div style="position: absolute; left:60px;">', ovni_get_field_searchable('Ovni model'),'</div>';
    	echo '<div style="position: absolute; left:100px;">', ovni_get_field_searchable('Rig'),'</div>';
    	echo '<div style="position: absolute; left:275px;">', ovni_get_field_searchable('Home waters'),'</div>';
    	echo '<div style="position: absolute; left:500px;">', ovni_get_field_searchable('Home port'),'</div>';
    
    }
    add_action( 'bp_directory_members_item', 'ovni_add_info_to_members_loop' );
    
    // the fuction that makes fields searchable according to the rules of this plugin
    function ovni_get_field_searchable($field_name) {	
    	global $ovni_no_link_fields, $ovni_social_networking_fields;
    	$field_value = xprofile_get_field_data($field_name, bp_get_member_user_id() );
    	
    	if ( $field_value) { // only if there is content in the field
    		if (is_array($field_value)){
    etc. etc.

    I have not included the code of my filter, but it is changing the way text in profile fields are turned into links, both when displayed in the directory entry and in the members list, thus:

    (1) If is an array, serialise into a comma-separated string
    (as used in outputing which social web sites a mobile number can be used for)
    (2) If is an image, change HTML so that clicking on image will open full size in new tab/window
    (3) If any field contians text in [ ], the contents of the [ ] pairs are turned into separate directory searches.
    So if the entire text is in [ ] it overrides all other rules
    (4) Fields in the list of ‘do not link’ fields are left plain
    (5) The user’s web site is converted to its URL
    (6) Fields containing social network user names are turned into links to those networks
    (7) The remaining are turned into links to search the directory for matches.

    It has been a learning curve. My formative programming of this type was in the language B (the antecedent of C), which shows how far back I go!

    thanks again for the help, Tony

    @adjunkten

    Participant

    @henrywright, thank you for sharing this.

    I am using your function #2 from above and it works.

    I would like to put a label before the profile field content, though, like

    (Label): (user content)

    (The label should not appear in the directory, when the user has not filled in the field.. )

    How do I modify your code to do that?

    @antipole

    Participant

    @henrywright… not sure exactly what you are doing, but you should be able to only generate the label when there is data

    if ($field_content){
          return "label: " . $field_content;
          }
    else return();
    

    @adjunkten

    Participant

    Thanks for answering, @antipode – but I don’t understand how to modify the code? (Obviously, I am not very coding skilled…)

    This is the function I am using from above:

    function add_info_to_members_loop() {
        echo bp_get_member_profile_data( 'field=the field name here' );
    }
    add_action( 'bp_directory_members_item', 'add_info_to_members_loop' );

    I would like the label to appear in members directory before the user’s profile field content, when the field is filled, if not there should be nothing.

    Thank you for your time.

    @shanebp

    Moderator

    Try:

    function add_info_to_members_loop() {
        $field_content = bp_get_member_profile_data( 'field=the field name here' );
        if( $field_content != false )
          echo "label: " . $field_content;
    }
    add_action( 'bp_directory_members_item', 'add_info_to_members_loop' );

    @adjunkten

    Participant

    Works like a charm!

    Thank you @shanebp!

    @wp_new_user

    Participant

    Hi, I wonder if there’s a way of doing the same by adding a function to bp-custom.php file?

    Thank you!

    @antipole

    Participant

    Sure – it could go in your bp-custom.php file.

    @wp_new_user

    Participant

    Hi @antipole, thanks. I made it.

    Now what I need is to remove a filed from there, for example, ‘active 2 minutes ago’, is it possible to remove it, too, using bp-custom.php?

    Thanks!

Viewing 16 replies - 1 through 16 (of 16 total)
  • The topic ‘Adding profile fields to members directory’ is closed to new replies.
Skip to toolbar