Rewrite rule that wp-login.php?action=register is left alone

I’m assuming that you’re working with one of the latest versions, but I used the latest 1.5.1. Without knowing how your specific Facebook Connect plugin works and why it breaks here’s what I’ve come up with.

Short answer

// bp-members/bp-members-signup.php ~ line 611
if ( defined( 'BP_SKIP_REGISTRATION_REDIRECT' ) and BP_SKIP_REGISTRATION_REDIRECT )
    wp_redirect( '/?pagename=register' );

And a filter:

function wpse31346_filter_bp_uri( $path ) {
    if ($path == '?pagename=register')
        return '/register';
    return $path;
}
add_filter( 'bp_uri', 'wpse31346_filter_bp_uri' );

Long answer

bp_core_wpsignup_redirect() is the function that contains the redirect you’re talking about.
http://buddypress.trac.wordpress.org/browser/tags/1.5.1/bp-members/bp-members-signup.php#L604

And as you can sadly see, there is no hook that allows you to alter the behavior. So you’ll most likely have to hack the BuddyPress core yourself.

By adding something like:

// Not at the WP core signup page and action is not register
if ( false === strpos( $_SERVER['SCRIPT_NAME'], 'wp-signup.php' ) && ( 'register' != $action ) )
    return;

if ( defined( 'BP_SKIP_REGISTRATION_REDIRECT' ) and BP_SKIP_REGISTRATION_REDIRECT ) return;

// Redirect to sign-up page
if ( locate_template( array( 'registration/register.php' ), false ) || locate_template( array( 'register.php' ), false ) )
    bp_core_redirect( bp_get_signup_page() );

Then simply add define( 'BP_SKIP_REGISTRATION_REDIRECT', true ) to your wp-config.php file an it should skip the redirect. However, accessing the link now will show the default WordPress registration page, ouch. This may disrupt user-experience.

The BuddyPress “rewriting” system is quite intricate (it’s called a “URI catcher”), in this case it breaks the request down and searches for an exact match in page slugs to provide the final URL, and the page slug in this case is register.

So let’s think a bit, what other way is there to access the register page in our case without resorting to the /register request? You’d be tempted to redirect to index.php?pagename=register, however that doesn’t work, that page is empty and isn’t being caught by the BuddyPress URI catcher, another ouch.

When register is identified in the /register URL it sets the $bp->current_component to register. However we can neither set the current_component to register nor directly call bp_load_template('registration/register') as the $bp global is has not been initialized at the point of redirection.

We can raise a flag perhaps? By implementing this hack:

if ( defined( 'BP_SKIP_REGISTRATION_REDIRECT' ) and BP_SKIP_REGISTRATION_REDIRECT ) {
    define( 'BP_SHOW_REGISTRATION_PAGE', true );
    return;
}

There appears to be no clean way of hooking into anything into this process, bp_load_template(), which gives us a chance to filter the template, will not be executed without the URI catcher’s match, it simply returns with the comment // This is not a BuddyPress page, so just return. http://buddypress.trac.wordpress.org/browser/tags/1.5.1/bp-core/bp-core-catchuri.php#L209

There is a filter high above in the function http://buddypress.trac.wordpress.org/browser/tags/1.5.1/bp-core/bp-core-catchuri.php#L54 called bp_uri, which we can potentially hook into to alter what BuddyPress perceives, like so:

function wpse31346_filter_bp_uri( $path ) {
    if ($path == '/wp-login.php?action=register')
        return '/register';
    return $path;
}
add_filter( 'bp_uri', 'wpse31346_filter_bp_uri' );

Yet, WordPress will still load its wp-login.php even in the event that we managed to match and hack BuddyPress into setting its current_component to register; bp_load_tempalate() is not being reached.

I remind you of the problem at hand – we can’t get the BuddyPress registration page to display after successfully stopping the redirect, just in case your forgot 🙂

The bp_screens action is fired off with the wp action, which is not fired off when wp-login.php is requested, so it’s off the hook. We can maybe redirect to ?pagename=register, bp_screens is fired off, so the bp_uri filter alterations will successfully avalanche over to bp_load_template().

Thus, after quite a long conversation with myself, I’m offering the following solution involving a core hack:

// bp-members/bp-members-signup.php ~ line 611
if ( defined( 'BP_SKIP_REGISTRATION_REDIRECT' ) and BP_SKIP_REGISTRATION_REDIRECT )
    wp_redirect( '/?pagename=register' );

And a filter:

function wpse31346_filter_bp_uri( $path ) {
    if ($path == '?pagename=register')
        return '/register';
    return $path;
}
add_filter( 'bp_uri', 'wpse31346_filter_bp_uri' );

Conclusion

Hopefully my answer has provided enough insight into how BuddyPress works and how inflexible this URI catching system appears to be. This is my first time looking into BuddyPress, so I must have probably missed something important while browsing the source code and documentation, so hopefully someone will provide some additional tips and solutions to improve the answer.

If you can provide more information on why it breaks and what is required by the Facebook Connect plugin I can further improve my answer. Maybe it doesn’t like the redirect at all? Or wants the standard WordPress login page? Can’t know without more info.