Extending Field Types
Extending Field Types
Section titled “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.

