Component slug vs root_slug in BP 1.3
One of the new features coming in BuddyPress 1.3 is the use of WP pages as top-level component directories. This makes it easier for BP site administrators to customize their site’s component URLs, even in a nested way. For instance, buddypress.org runs a single installation of BuddyPress, with forums directory associated with a WP page called Topics, which is a child of the top level page Support (thus the URL buddypress.org/support/topics), while the members directory is on a page called Members with parent page Community (thus buddypress.org/community/members/boonebgorges).
To allow this flexibility with top-level component slugs, some elements of the $bp global have been changed in ways that plugin authors must account for in order for their plugins to be fully compatible with BP 1.3. In BP 1.3, in addition to a slug, each component with a top-level directory (and associated WP page) has a root_slug. To see how the new root_slug is defined, let’s look at how the forums component does it, using the example of buddypress.org and the URLs I described above.
if ( !defined( 'BP_FORUMS_SLUG' ) )
define ( 'BP_FORUMS_SLUG', bp_core_component_slug_from_root_slug( $bp->pages->forums->slug ) );
// Slugs
$bp->forums->slug = BP_FORUMS_SLUG;
$bp->forums->root_slug = $bp->pages->forums->slug;
The root_slug is set to $bp->pages->forums->slug, which in the case of buddypress.org is the string 'support/topics'. The new function bp_core_component_slug_from_root_slug() creates $bp->forums->slug by taking everything after the final / in the root_slug – in this case, ‘topics’.
These changes matter for your plugin in two different ways.
- Concatenating URLs – When building URLs, make sure you are choosing correctly between the slug and the root slug. When the slug appears at the beginning of the URL (immediately after the root domain for the BP installation), use the root_slug. For example,
$group_directory_link = bp_get_root_domain() . $bp->groups->root_slug;
is the correct code for creating a URL like example.com/groups. On the other hand, you should use the slug when it will appear mid-URL (primarily in the members component). For example,
$my_groups_link = bp_loggedin_user_domain() . $bp->groups->slug;
will return the link for a user’s groups, such as example.com/members/boonebgorges/groups. - Checking the current_component – In BP and BP-dependent plugins, it has been common to see which component you are using by comparing the value of
$bp->current_componentwith the component slug. In BP 1.3, this will not work in all cases, since sometimes the current_component will match the slug, and other times it will match the root_slug. BP 1.3 introducesbp_is_current_component(), which is an all-purpose function for generously detecting your current component. It takes slugs (‘topics’), root slugs (‘support/topics’) and component names (‘forums’) as arguments. You should replace all of your plugin’s current_component/slug checks with this function instead. In other words, replace things like this:
if ( $bp->current_component == $bp->groups->slug )
with
if ( bp_is_current_component( $bp->groups->slug ) )
If you fail to make these changes, your plugin will stop working whenever a BP site admin creates a directory with a complex URL, or defines one of the BP_X_SLUG constants to override the non-root_slug.
For more information, see the associated commit [3728] and the corresponding discussion #2600.
marshallsorenson 12:21 pm on January 19, 2011 Permalink |
Plugins should somehow be checked to see if they have made these changes, otherwise they should not be allowed to be registered as root components or to create navigation items in 1.3. Maybe checking for a $bp->foo->root_slug is good enough?
People will try to use plugins even if they are not compatible yet and possibly fark their installs.
John James Jacoby 6:30 am on January 20, 2011 Permalink |
I like having slugs and root_slugs, and there will be proper fallbacks and API to handle the getting and setting of these different areas of the site. Most of this exists already, but there is still more to do.
Ray 1:18 am on February 4, 2011 Permalink |
I didn’t post this as a Trac ticket yet because I wasn’t sure, but is $bp->root_components being deprecated in BP 1.3?
I took a quick look at /bp-core/bp-core-loader.php in trunk and $bp->root_components doesn’t appear to be in the code at the moment.
Ray 1:39 am on February 10, 2011 Permalink |
Does $bp->active_components take the place of $bp->root_components?
Maintaining 1.2 compatibility: slugs « BuddyPress Development Updates 3:52 pm on July 31, 2011 Permalink |
[...] I discussed in a recent post, BP 1.5′s slug setup is a bit different. To ensure full compatibility with all BP 1.5 setups [...]
T. J. Brumfield 4:13 am on August 8, 2011 Permalink |
I’m trying to learn this from scratch, and I’m at a loss here.
I don’t want everything having a top level page. So let’s say I set my page for a bp plugin as a child page of members. This works fine for core components as I have activity and groups under members. In BP 1.5 I see you use bp_get_groups_root_slug() which in turn basically returns $bp->groups->root_slug and I’m not sure how that is being set.
For plugin FOO, I’ve tried setting it with $bp->pages->FOO and $bp->pages->foo->SLUG which are both empty even though there is a page assigned. $bp->FOO->root_slug is also empty.
How do I get the value of the actual page location?
It should be members/FOO for as I have the page under members.
Boone B. Gorges 7:08 pm on August 9, 2011 Permalink |
If you don’t want a top level page then you don’t need to worry about root slugs. Likewise with $bp->pages – that’s only relevant for top-level components.
For your purpose, you can use the very same technique used in earlier versions of BP, as foxly points out below. That is, two steps:
1) Put some of your information in the $bp global, by hooking to bp_setup_globals. Here’s how BP Media does it: http://code.google.com/p/buddypress-media/source/browse/bp_album/trunk/includes/bp-album-core.php#60
2) Then, set up the navigation using bp_core_new_nav_item() and the globals you set up in (1). This should be hooked to bp_setup_nav. See BP Media: http://code.google.com/p/buddypress-media/source/browse/bp_album/trunk/includes/bp-album-core.php#159
foxly 4:28 am on August 8, 2011 Permalink |
We had to solve the same problem.
You can literally cut and paste from the code in our plugin BuddyPress Media, http://code.google.com/p/buddypress-media/source/browse/bp_album/trunk/includes/bp-album-core.php lines 159 to 218.
^F^