Extending BuddyPress Group Hierarchy – Creating a Member Groups list

In this post, I’m going to show you how to create a Member Groups page/list/widget, with a little background on how Group Hierarchy extends the BuddyPress Groups loop.

BuddyPress Groups loop overview

If you aren’t familiar with bp_has_groups() from looking at the BuddyPress theme files, you should take a look at this overview from the BP Codex before continuing.

In a nutshell, bp_has_groups() accepts a series of parameters which it uses to populate the global $groups_template variable with a set of groups. This, in turn, allows all the cool template functions to work without parameters cluttering up your theme file.

How Group Hierarchy changes the Loop

BuddyPress Group Hierarchy changes this in two important ways:

  1. bp_has_groups() creates a set of BP_Groups_Hierarchy objects instead of BP_Groups_Group objects
  2. bp_has_groups_hierarchy() extends the loop with a parent_id parameter for getting only child groups of the passed group ID

There are more changes made just for the Group Tree, but that’s enough to get us started. Onward!

Creating a Member Groups list

Before we build our Member Groups page / widget / list, there’s something you should know about working “in the loop,” i.e. in the context of the current group. The only thing telling BuddyPress what group we’re looking at is the $groups_template variable introduced above. Our member group list is going to change that variable, so we need to save its current state and restore it when we’re done.

// If you're in a function, bring $groups_template into scope
global $groups_template;
 
// Save the current group context for later
$current_group_template = $groups_template;

Using the Codex article I posted at the top as a reference, you’ll see how easy it is to create a Member Groups page / widget / whatever.

Just replace:

<?php if ( bp_has_groups() ) : ?>

with:

<?php if ( bp_has_groups_hierarchy( array( 
	'type'      => 'alphabetical',
	'parent_id' => bp_get_current_group_id() 
) ) ) : ?>

…and the rest works as is! Since 1.3.0, pagination is handled automatically.

Don’t forget to restore the original context!

$groups_template = $current_group_template;

A complete example

Here’s a quick example that adds a list of Member Groups on the Members page, above the list of users. Drop this in your functions.php file, or in a custom plugin, but note that it will only display if the parent group has at least one member!

<?php
add_action( 'bp_before_group_members_content', 'my_func_list_member_groups' );
 
function my_func_list_member_groups() {
	// If you're in a function, bring $groups_template into scope
	global $groups_template;
 
	// Save the current group context for later
	$current_group_template = $groups_template;
 
	if ( bp_has_groups_hierarchy( array( 
		'type'      => 'alphabetical',
		'parent_id' => bp_get_current_group_id(),
	) ) ) : ?>
 
	<h3><?php _e( 'Member Groups' ); ?><br />&nbsp;</h3>
 
	<div class="pagination">
 
		<div class="pag-count" id="group-dir-count">
			<?php bp_groups_pagination_count() ?>
		</div>
 
		<div class="pagination-links" id="group-dir-pag">
			<?php bp_groups_pagination_links() ?>
		</div>
 
	</div>
 
	<ul id="groups-list" class="item-list">
	<?php while ( bp_groups() ) : bp_the_group(); ?>
 
		<li>
			<div class="item-avatar">
				<a href="<?php bp_group_permalink() ?>"><?php bp_group_avatar( 'type=thumb&width=50&height=50' ) ?></a>
			</div>
 
			<div class="item">
				<div class="item-title"><a href="<?php bp_group_permalink() ?>"><?php bp_group_name() ?></a></div>
				<div class="item-meta"><span class="activity"><?php printf( __( 'active %s ago', 'buddypress' ), bp_get_group_last_active() ) ?></span></div>
 
				<div class="item-desc"><?php bp_group_description_excerpt() ?></div>
 
				<?php do_action( 'bp_directory_groups_item' ) ?>
				</div>
 
			<div class="action">
				<?php bp_group_join_button() ?>
 
				<div class="meta">
					<?php bp_group_type() ?> / <?php bp_group_member_count() ?>
				</div>
 
				<?php do_action( 'bp_directory_groups_actions' ) ?>
			</div>
 
			<div class="clear"></div>
		</li>
 
	<?php endwhile; ?>
	</ul>
 
		<?php do_action( 'bp_after_member_groups_loop' ) ?>
 
	<?php else: ?>
 
		<div id="message" class="info">
		<p><?php _e( 'There were no member groups found.' ) ?></p>
		</div>
 
	<?php endif;
 
	// restore original group context!
	$groups_template = $current_group_template;
}

That’s it! Drop me a line in the comments if you find a novel use for this technique.

8 Responses

  1. Hi David,

    I'm trying to figure out how to make the Group Tree only show child groups if the current user is a member of the parent group. Any thoughts on how to approach it?

    • ddean says:

      Hi Corey,

      You can use <code>bp_group_is_member()</code>, which will return whether the current user is a member of the current group. In the example above, you'd probably just return from the <code>my_func_list_member_groups()</code> function if the user is not a member, but you could also print a message about needing to join to see member groups.

      Just make sure to call it before <code>bp_has_groups_hierarchy()</code>, or it will be checking against the child groups!

  2. Ben says:

    Hey David,

    How would I us the bp_group_hierarchy_has_parent() function? Say if I wanted to hide a certain <div> if the group was not the parent group?
    I am currently trying to do it like so;

    <?php if ( bp_group_hierarchy_has_parent() ) { ?>
    <div> I am hidden </div>
    <?php } else { ?>
    <div> I am NOT </div>

    Thanks mate :)

    • ddean says:

      Ben,

      I'm a little confused by what you mean. Are you speaking generally or just about this post?

      Let me know and I'll be happy to help!

  3. Ben says:

    sorry about that, I am speaking generally. I would of emailed the question but couldn't find an email address on the site. I am making a site that has the top groups as DVD listings and I would like to let the members to make sub-groups for each top group but I don't want sub-groups to have sub-groups (limit top groups to have a hierarchy level of 1).

  4. Johnny says:

    We are approaching 1000 groups at http://tradr.com

    It is a struggle to get a good 'sitemap' format of all groups.

    Is it possible to turn this code into a shortcode to display on a page?

    Thanks for any help,

    Johnny

    • ddean says:

      Hi, Johnny!

      This code will only show the level below the current group. bp_has_groups_hierarchy() allows you to select groups by parent_id, but doesn't give you all groups.

      You can use the BP_Groups_Hierarchy::get_tree() method to get the whole tree. It'll still take some processing to arrange the groups into a sitemap, but that's the function to start with.

  5. I see that you have developed a number of BuddyPress plugins. There is one that would be great. When a member is on the activity stream, it would be great if there was a plugin that permitted a member to post to a number of groups at once.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>