BuddyPress is one of the oldest and, in my opinion, best community plugins for WordPress. For absolutely free, it allows you to quickly set up a community platform on your website with groups, different user types, directories, and other basic features. And if you want to add something more specific to its basic functionality, there are many BuddyPress free and premium extensions.
Today, I want to show you how to extend default BuddyPress features without plugins. Unfortunately, I can’t say that the BuddyPress documentation is too comprehensive. Neither I can’t say that there are as many BuddyPress tutorials as we can find for WooCommerce, for example. But, as I already said in one of my previous posts, being a WordPress blogger, I see the lack of content I’d be interested in as an opportunity for myself.
So, in this post, I’m going to show you how to add custom fields to BuddyPress groups. No plugins: just custom PHP code. Let’s get started!
What are we going to build?
Recently, checking new questions on WordPress Development Stack Exchange, I stumbled upon a question on how to hide BuddyPress groups for anonymous users without making them private.
And I think that it’s a good goal for our today’s tutorial. We’re going to add a custom checkbox for BuddyPress groups which value will change if a group’s content is available for anonymous users.
To achieve this, we’ll need to add this checkbox to three different forms:
- The “Edit Group” form in the WordPress admin dashboard
- The “Create a Group” form on the frontend
- The “Manage” form on a group’s page that is available for the group’s admins
The logic will be pretty simple: if a checkbox is checked, we have to redirect all anonymous users trying to access a group’s page to the login page.
How to add custom admin meta box to BuddyPress groups
In the bp-groups folder, you can find the bp-groups-admin.php file. Here you can see the bp_groups_admin_load() function that is responsible for registering the default BuddyPress groups meta boxes.
Since we want to add a custom meta box there, we’re interested in this function because it calls the bp_groups_admin_meta_boxes action. Citing the developers, this hook “fires after the registration of all of the default group meta boxes“. This means we can use it to register our own meta boxes.
Here’s the code I’ll use:
add_action( 'bp_groups_admin_meta_boxes', 'bpgcp_add_admin_metabox' );
function bpgcp_add_admin_metabox() {
add_meta_box(
'bp_content_protection', // Meta box ID
'Content Protection', // Meta box title
'bpgcp_render_admin_metabox', // Meta box callback function
get_current_screen()->id, // Screen on which the metabox is displayed. In our case, the value is toplevel_page_bp-groups
'side', // Where the meta box is displayed
'core' // Meta box priority
);
}
The meta box is registered, so now we need to write the callback function that will be used to render its content:
<?php
function bpgcp_render_admin_metabox() {
$group_id = intval( $_GET['gid'] );
$hide_from_anonymous = intval( groups_get_groupmeta( $group_id, 'hide_from_anonymous' ) );
?>
<div class="bp-groups-settings-section" id="bp-groups-settings-section-content-protection">
<fieldset>
<legend>Hide the group's content from anonymous users?</legend>
<label>
<input type="checkbox" name="hide_from_anonymous" value="1" <?php checked( $hide_from_anonymous ) ?>>
Yes
</label>
</fieldset>
</div>
<?php
}
As you see, in the example above, I define two variables.
I take the current group ID from the gid query parameter. You can see it in the URL every time you edit a group in the admin editor.
And the second one, $hide_from_anonymous, is the result of the groups_get_groupmeta() function’s call. You can take it as the BuddyPress groups’ equivalent of the get_post_meta() function.
The other parts of the code are pretty similar to what you usually do when you register the regular posts’ meta boxes.
Now, let’s check the results of our code:
Yep, works just like expected. But the problem is that this is just a piece of HTML. The value of the checkbox is not saved or updated when you click the “Save Changes” button at the moment. Let’s fix it.
How to save custom BuddyPress groups meta fields
In the same bp_groups_admin_load() function, we can find the bp_group_admin_edit_after hook. Yeah, I know: that’s strange that the same function handles the displaying and the saving of the field. But that’s what we’ve got.
Anyways, as the developers say, this hook “fires before redirect so plugins can do something first on save action“. This means that we can use it to insert or update our custom groups’ meta fields.
add_action( 'bp_group_admin_edit_after', 'bpgcp_save_metabox_fields' );
function bpgcp_save_metabox_fields( $group_id ) {
$hide_from_anonymous = intval( $_POST['hide_from_anonymous'] );
groups_update_groupmeta( $group_id, 'hide_from_anonymous', $hide_from_anonymous );
}
Note: I use the intval() function to make sure that the value will always be an integer and to sanitize the value. You have to always sanitize your dynamic variables if you’re going to insert them into the database.
With this code, we can mark this feature as completed. The anonymous protection group’s feature is now modifiable from the admin dashboard.
How to add custom fields to the “Create a Group” form
If you’ve already tried to create groups in BuddyPress from the frontend, you probably know that the group creation form is divided into several steps (screens). So, based on where exactly you want to display your custom fields there, you need to use different hooks.
Under the hood, the group creation form uses the bp_nouveau_group_creation_screen() function to render the current screen. This function, in turn, is defined in the bp-templates/bp-nouveau/includes/groups/template-tags.php. Inspecting its code, you can see the following piece of code:
/**
* Fires before the display of group delete admin.
*
* @since 1.1.0 For most hooks.
* @since 2.4.0 For the cover image hook.
*/
do_action( 'bp_after_' . $core_screen['hook'] );
This hook fires at the end of each form’s screen right before the buttons.
The dynamic $core_screen[‘hook’] means that you need to use the hook name of the step you need.
I decided that the feature we’re adding is more related to the Group Settings screen, so I’m going to add my custom checkbox there. This means the hook I need to use is bp_after_group_settings_creation_step. Here’s the full list of default hooks you can use to display your custom fields in this form:
- bp_after_group_details_creation_step
- bp_after_group_settings_creation_step
- bp_after_group_avatar_creation_step
- bp_after_group_cover_image_creation_step
- bp_after_group_invites_creation_step
Now, let’s add a function that will display our custom checkbox:
<?php
add_action( 'bp_after_group_settings_creation_step', 'bpgcp_render_settings_in_create_form' );
function bpgcp_render_settings_in_create_form() {
?>
<fieldset class="radio content-privacy">
<legend>Content Protection</legend>
<p>Hide the group's content from anonymous users?</p>
<label>
<input type="checkbox" name="hide_from_anonymous" value="1">
Yes
</label>
</fieldset>
<?php
}
And here’s how it looks:
And again, by default, BuddyPress doesn’t know anything about our custom checkbox. We have to save and update its value on our own.
How to save custom fields from the group creation form
The steps-based nature of the group creation forms lets us know about itself again. In the bp-groups/actions/create.php, you can find the function responsible for saving the data from the group creation form. It’s called groups_action_create_group(), and in its code, we can see these lines of code:
/**
* Fires before finalization of group creation and cookies are set.
*
* This hook is a variable hook dependent on the current step
* in the creation process.
*
* @since 1.1.0
*/
do_action( 'groups_create_group_step_save_' . bp_get_groups_current_create_step() );
So, the logic is pretty similar to what we had in the previous section. The hook I need to use to save my custom field is groups_create_group_step_save_group-settings. And here’s the code I’m going to use:
add_action( 'groups_create_group_step_save_group-settings', 'bpgcp_save_settings_from_create_form' );
function bpgcp_save_settings_from_create_form() {
$group_id = bp_get_current_group_id();
// bp_get_current_group_id() may return 0 at the first step
if ( $group_id === 0 ) {
$group_id = buddypress()->groups->new_group_id;
}
$hide_from_anonymous = intval( $_POST['hide_from_anonymous'] );
groups_update_groupmeta( $group_id, 'hide_from_anonymous', $hide_from_anonymous );
}
Note that in this case, we don’t have the gid query parameter or anything like this. But, we still do have access to the current group ID by using the bp_get_current_group_id() function. The other parts of the code are the same.
How to add custom fields to the group’s “Manage” form?
Note: this part of the post is written assuming that you use the default bp-themes/bp-default/groups/single/admin.php template for the managing area.
At the moment, the only way to change the value of the hide_from_anonymous group’s meta field is to use the group editor in the WordPress dashboard. But what if we’d want to allow a group’s administrators, which can be regular users, to edit this field from the “Manage” form?
The group managing area is divided into sections. Each section has its own template. Since we’ve added our custom checkbox to the Group Settings tab, we need to modify its template for the managing area.
Here’s the code I’m going to use to display my custom checkbox:
<?php
add_action( 'bp_after_group_settings_admin', 'bpgcp_render_settings_in_edit_form' );
function bpgcp_render_settings_in_edit_form() {
$group_id = bp_get_current_group_id();
$hide_from_anonymous = intval( groups_get_groupmeta( $group_id, 'hide_from_anonymous' ) );
?>
<fieldset class="radio content-privacy">
<legend>Content Protection</legend>
<p>Hide the group's content from anonymous users?</p>
<label>
<input type="checkbox" name="hide_from_anonymous" value="1" <?php checked( $hide_from_anonymous ) ?>>
Yes
</label>
</fieldset>
<?php
}
Now, if I go to Group -> Manage -> Settings and scroll the page down, I see my custom checkbox here:
How to save custom fields from the group settings
This time, the code I’ll use will be universal for all BuddyPress-based themes.
The process of saving and updating the “Group Settings” section’s fields is handled by the groups_screen_group_admin_settings() function.
On every settings’ save the groups_group_settings_edited hook is getting fired, so we’ll use it to update our custom field’s value:
add_action( 'groups_group_settings_edited', 'bpgcp_save_settings_from_edit_form' );
function bpgcp_save_settings_from_edit_form( $group_id ) {
$hide_from_anonymous = intval( $_POST['hide_from_anonymous'] );
groups_update_groupmeta( $group_id, 'hide_from_anonymous', $hide_from_anonymous );
}
How to hide a BuddyPress group from the anonymous users?
Now, having the modifiable hide_from_anonymous field in all forms that allow users to create or update a group, we can implement the content protection logic we discussed in the beginning:
add_action( 'template_redirect', 'redirect_anonymous_users_to_login_form' );
function redirect_anonymous_users_to_login_form() {
if ( ! bp_is_group() ) {
return;
}
if ( is_user_logged_in() ) {
return;
}
$group_id = bp_get_current_group_id();
$hide_from_anonymous = intval( groups_get_groupmeta( $group_id, 'hide_from_anonymous' ) );
if ( $hide_from_anonymous ) {
wp_safe_redirect( wp_login_url(), 302 );
}
}
The only BuddyPress-related function that I use here is bp_is_group(). It’s a template tag that, as you might have guessed, returns true if the current page is a BuddyPress group’s page. You can learn more about the BuddyPress template tags in the official Template Tag Reference.
Summary
As I already said, there’s not too much information about the proper ways to extend BuddyPress with some custom code. So I hope that this post made the situation a little bit better.
As always, feel free to ask any questions in the comments section under this post.
Don’t forget to follow me on LinkedIn to stay updated with new posts and tweets on things I learn or do.
Thank you for your attention; see you in the next one!
Wow Artemy you are doing such a great job at explaining for newbies like me!
Thank you so much for taking the time because as you said there are not many BP tutorials out there.
By the way it worked like a charm except that I needed to add an exit after the redirect like this :
Keep doing the amazing work and be well my friend! 🙂
Hi Emmanuel! Thank you for your words! I’m glad that my post has helped you 🙂
Really enjoyed this tutorial! In the site I’m updating I want to include the field in the Buddypress Group header under the Group Description. What action would we use to include the custom field in the Group header under the Group Description?
Hi! Thank you for the comment. Could you clarify what placement you mean by providing a screenshot?
I think this person would like the same thing I’m going for here. To be able to fetch the new field from the database that was entered on group creation and display that on the front-end in Group Header. So Group Name Title, Group Description, then the New Custom Field.
Hi Cristina,
It depends on your setup. What theme do you use?
Thank you for replying! I’m using Elementor with the Anesta Extranet theme.
Hi Cristina! Unfortunately, I haven’t worked with this specific theme and it doesn’t have a free version so I can’t check it.
However, if you want to render your custom field on the group page, you need to find the template of the page (or the specific template of the group header if that’s your case), and then use the groups_get_groupmeta() function to retrieve the value of your custom field.
Excellent tutorial and it saved my hours of time. Thanks so much for sharing.
You’re welcome! Thank you for the comment 🙂
But how to upload attchments
Hello, abhishek
Well, this one is more complicated. You can use this specific post as the foundation, but you’ll also need implement the file uploading, validation, etc.
Maybe I’ll write a post on this topic in the future, thank you for the idea 🙂
You can also try this plugin: https://wordpress.org/plugins/bp-attachments/
This is amazing!!! Is there a way to render the custom field on the frontend?
Hi Cristina, thank you for your comment!
It depends on where exactly you want to render it.