Extending Field Types
BuddyPress Profile Pro lets you register new field types without editing the plugin files. New types appear in the admin field-type dropdown alongside the 14 built-in types, and they participate in the same rendering pipeline.
All code goes in your theme’s functions.php or a small site-specific plugin. Never edit the plugin files directly - updates will overwrite those changes.
How the extension path works
Section titled “How the extension path works”A custom field type has three required surfaces and one optional surface:
| Surface | What it controls | How to add it |
|---|---|---|
| Admin - type registration | The type key and label in the Field Type dropdown | wbbpp_add_extra_field_types filter |
| Frontend - input HTML | The form field shown on the profile edit tab and on the registration form | A PHP function named bprm_get_field_{type_key}_html() |
| Frontend - display (profile tab) | How the saved value looks when viewing the profile’s Extended Fields tab | wbbpp_render_extra_field_type_content filter |
| Frontend - display (profile loop) | How the value looks in the profile loop / shortcode render | wbbpp_render_extra_field_type_content_cases filter |
The plugin dispatches the input function by calling:
call_user_func( 'bprm_get_field_' . $field_type . '_html', $fields, $field_name, $resume_data, $grp_key, $key3, $user_id );Both display filters use the same three-parameter signature and fall into the default branch of the built-in switch block, so they only fire for types that are not already handled by a native case.
Step 1 - Register the type key
Section titled “Step 1 - Register the type key”Add your type to the wbbpp_add_extra_field_types filter. The key becomes the internal identifier used throughout the plugin; the value is the label shown in the admin dropdown.
add_filter( 'wbbpp_add_extra_field_types', function( $field_types ) { $field_types['color_picker'] = 'Color Picker'; return $field_types;} );Source: admin/inc/wbbpp-resume-filter-functions.php, inside bprm_resume_field_types()
After registering the key, the admin UI lets you create fields of type color_picker. You must complete the steps below before those fields render correctly on the frontend.
Step 2 - Provide the input function
Section titled “Step 2 - Provide the input function”The plugin calls bprm_get_field_{type_key}_html() from two templates:
public/buddypress-template/wbbpp-add-profile.php- the profile edit tabpublic/buddypress-template/wbbpp-add-register-profile-field.php- the registration form
Define the function globally (in functions.php or a plugin file). Use this signature - it matches every built-in type such as bprm_get_field_textbox_html():
/** * Render the color picker input. * * @param array $fields Full field config array for this field. * @param string $field_name The field's internal key (e.g. 'my_color'). * @param mixed $resume_data The user's saved data for the current group (may be empty string on registration). * @param string $grp_key Group key (e.g. 'bprm_contact_details'). * @param int $key3 Repeater group index (0 for the first or only row). * @param int $user_id The user being edited (0 on registration). */function bprm_get_field_color_picker_html( $fields, $field_name, $resume_data, $grp_key, $key3, $user_id ) { $g_key = ( 0 !== $key3 ) ? '_' . $key3 : ''; $field_meta_key = 'wbbpp_' . $grp_key . $g_key . '_' . $field_name; $saved_value = $user_id ? get_user_meta( $user_id, $field_meta_key, true ) : ''; $saved_value = is_array( $saved_value ) ? '' : esc_attr( $saved_value );
$required_attr = ! empty( $fields['bprm_nf_required'] ) ? 'required' : ''; $required_class = ! empty( $fields['bprm_nf_required'] ) ? 'bprm-required' : ''; ?> <div class="field-<?php echo esc_attr( $field_name ); ?> bprm-field-contain"> <input class="inp-text <?php echo esc_attr( $required_class ); ?>" type="color" name="wbbpp_userdata[<?php echo esc_attr( $grp_key ); ?>][<?php echo esc_attr( $key3 ); ?>][<?php echo esc_attr( $field_name ); ?>][0]" value="<?php echo $saved_value ?: '#000000'; ?>" <?php echo esc_attr( $required_attr ); ?> > </div> <?php}Key rules:
- The
nameattribute must follow the patternwbbpp_userdata[{grp_key}][{key3}][{field_name}][{index}]. The plugin’s save routine reads$_POST['wbbpp_userdata']and writes each value to the meta keywbbpp_{grp_key}{g_key}_{field_name}{f_key}- as long as thenameattribute is correct, the built-in save handles everything. - For repeater fields, loop from
0to$field_count - 1and suffix each meta key and eachnameindex accordingly. Seebprm_get_field_textbox_html()for the repeater pattern. - If the function does not exist when the dispatch runs, PHP triggers a fatal error. Always define the function before any page that renders a field of your type.
Step 3 - Render the display value
Section titled “Step 3 - Render the display value”The plugin renders saved values using two separate templates, each with its own filter. You need to hook both.
wbbpp_render_extra_field_type_content
Section titled “wbbpp_render_extra_field_type_content”Controls the display in public/buddypress-template/wbbpp-render-profile.php. This template powers the Extended Fields profile tab. It receives the default branch of the function bprm_render_field_type_html_for_resume().
Filter signature:
apply_filters( 'wbbpp_render_extra_field_type_content', $field_type, $value_to_render, $field_name )| Parameter | Type | Notes |
|---|---|---|
$field_type |
string |
The type key registered in Step 1 |
$value_to_render |
mixed |
Saved meta value - may be a scalar, an array, or an array of arrays depending on field and repeater configuration |
$field_name |
string |
The field’s internal key |
Source: public/buddypress-template/wbbpp-render-profile.php, line 198
wbbpp_render_extra_field_type_content_cases
Section titled “wbbpp_render_extra_field_type_content_cases”Controls the display in public/buddypress-template/wbbpp-profile-render-cases.php. This template is used by the profile loop and the [wbbpp_show_profile] shortcode. It receives the default branch of bprm_profile_render_field_type_html_for_resume().
Filter signature:
apply_filters( 'wbbpp_render_extra_field_type_content_cases', $field_type, $value_to_render, $field_name )Parameters are identical to wbbpp_render_extra_field_type_content.
Source: public/buddypress-template/wbbpp-profile-render-cases.php, line 238
Example - hook both filters
Section titled “Example - hook both filters”/** * Render a saved color picker value. * * @param string $field_type The type key (we only act on 'color_picker'). * @param mixed $value_to_render Saved meta value. * @param string $field_name The field's internal key. * @return string HTML string, or empty string for unrecognized types. */function my_plugin_render_color_picker( $field_type, $value_to_render, $field_name ) { if ( 'color_picker' !== $field_type ) { // Return an empty string - do NOT return $field_type or you will corrupt output. return ''; }
// The value arrives as whatever was stored by the save routine. // For a simple non-repeater field this is typically a scalar string. $color = is_array( $value_to_render ) ? ( $value_to_render[0] ?? '' ) : $value_to_render; $color = esc_attr( (string) $color );
return '<div class="fields-items ' . esc_attr( $field_name ) . ' color_picker">' . '<span class="color-swatch" style="background:' . $color . '; display:inline-block; width:20px; height:20px; border:1px solid #ccc;"></span>' . ' ' . esc_html( $color ) . '</div>';}
add_filter( 'wbbpp_render_extra_field_type_content', 'my_plugin_render_color_picker', 10, 3 );add_filter( 'wbbpp_render_extra_field_type_content_cases', 'my_plugin_render_color_picker', 10, 3 );Important: Both filters pass control only when the switch block reaches its default case - meaning the type key is not one of the 14 built-in types. Always guard with a if ( 'your_type_key' !== $field_type ) { return ''; } check so your handler ignores types it does not own.
Step 4 - Saving (automatic for most types)
Section titled “Step 4 - Saving (automatic for most types)”The plugin saves all extended profile data in wbbpp-add-profile.php by reading $_POST['wbbpp_userdata'] and writing each value to user meta. You do not need a custom save handler as long as:
- Your input’s
nameattribute follows the pattern from Step 2. - Your value is a scalar or a simple array.
The meta key written is:
wbbpp_{group_key}{group_key_suffix}_{field_name}{field_index_suffix}For example: field my_color in group bprm_contact_details (index 0) is stored under:
wbbpp_bprm_contact_details_my_colorFor repeater groups at row index 1: wbbpp_bprm_contact_details_1_my_color.
The save routine uses array_walk_recursive( $data, 'bprm_sanitize_data' ) before writing, which applies sanitize_text_field() to every leaf. If your type stores structured data (e.g. JSON), handle serialization before the form submit or override the name pattern to store as a scalar.
Step 5 - Search support (optional)
Section titled “Step 5 - Search support (optional)”By default, the member search system does not know about your new type. If you want members to be searchable by a color_picker field value, you need to handle it in the search layer. The plugin exposes these extensibility points:
wbbpp_search_resultsfilter - modifies search results array (public/class-buddypress-profile-pro-public.php)wbbpp_search_usersfilter - modifies the user query object before execution
See the filter parameter details in the search-related sections of this guide above.
Complete checklist
Section titled “Complete checklist”| Step | What you add | Required? |
|---|---|---|
| 1 | wbbpp_add_extra_field_types filter |
Yes |
| 2 | bprm_get_field_{type_key}_html() function |
Yes |
| 3a | wbbpp_render_extra_field_type_content filter |
Yes |
| 3b | wbbpp_render_extra_field_type_content_cases filter |
Yes |
| 4 | Custom save handler | Only for structured/complex data |
| 5 | Search integration | Only if the field should be searchable |
Template override alternative
Section titled “Template override alternative”Some of the plugin’s front-end templates support theme overrides; others do not. Whether a theme copy takes precedence depends on how the plugin loads each file.
Supports theme override - these three files are loaded via locate_template() in public/class-buddypress-profile-pro-public.php, so placing a copy at the path below causes the theme version to load instead of the plugin version:
your-theme/└── buddypress-profile-pro/ ├── wbbpp-add-profile.php ← controls the add/edit profile form ├── wbbpp-show-profile.php ← controls the public profile display └── wbbpp-add-register-profile-field.php ← controls the registration form fieldDoes not support theme override - the following files are loaded via require_once with a hardcoded plugin path in includes/class-buddypress-profile-pro.php (lines 117, 133, 138). Placing copies in your theme directory has no effect:
wbbpp-dropdown-options.phpwbbpp-render-profile.phpwbbpp-profile-render-cases.php
To extend field type rendering in those files, use the PHP filters described in Steps 2-3 (wbbpp_render_extra_field_type_content and wbbpp_render_extra_field_type_content_cases). The filter-based approach is the only supported extension point for those files and works without duplicating entire template files.
Notes on the built-in type slugs
Section titled “Notes on the built-in type slugs”The 14 built-in type keys are defined in bprm_resume_field_types(). Do not reuse any of them in your wbbpp_add_extra_field_types callback - returning an existing key under the same array position overwrites the built-in label but the display switch cases still handle that key natively, so your display filters will never fire for it.
The key calender_field is a known spelling inconsistency in the codebase (should be calendar_field). Do not correct it in your code - existing data uses this key and the built-in cases match on it exactly.

