Improving custom component installation

When implementing a custom component in BuddyPress, you will often have additions for the member theme. Member themes live in their own folder, /wp-content/bp-themes/.

To render a member theme template, your component will call dpa_load_template() which takes an argument of the name of the template to load. The path is hardcoded to the /wp-content/bp-themes/ folder.

The problem with this is that after installation of a custom component, the site administrator will need to move the relevant member theme files (bundled with your component) into /wp-content/bp-themes/. This is an annoyance to site administrator, and it may end up being a frequent support request (“why is X not working?”).  This very first hurdle may even stop people trying out your component.

Something else I’ve seen is that when installing future updates, people may forget that they need to move the updated member theme files into place; this can cause incompatibility issues between versions of your software, something we’ve seen with recent versions of BuddyPress.

For my upcoming “Achievements” plugin (think a cross between forum points and Xbox Live), I decided all that I wanted the site administrator to do would be to download it from the Plugins admin panel – no moving files into the member theme.

So, I present to you my code: (06/01/10 – updated for BP 1.1.3+)

bp_core_load_template( 'yourcomponent_theme_filename' );  // loads /plugins/your_plugin/filename.php

function yourcomponent_screen_filter_template( $located_template, $template_name ) {
	if ( !empty( $located_template ) )
		return $located_template;

	if ( $bp->current_component != $bp->your_component->slug )
		return false;

	if ( false !== strpos( $template_name[0], 'yourcomponent_theme_' ) ) {
		$prefix = strlen( 'yourcomponent_theme_' );
		$template_name = substr( $template_name[0], $prefix, strlen( $template_name[0] ) - $prefix );
		$template_path = WP_PLUGIN_DIR . "/your_plugin/$template_name";

		if ( file_exists( $template_path ) )
			return $template_path;

	return false;
add_filter( 'bp_located_template', 'yourcomponent_screen_filter_template', 10, 2 );