How to Build a Facebook-Style Members-Only WordPress-BuddyPress Site

How to Build a Facebook-Style Members-Only WordPress-BuddyPress Site

lock

The WordPress-Buddypress-Lockdown challenge

I often read about folks wanting to lockdown their WordPress-Buddypress site, and make it so that content is accessible to logged-in members only. Even more, many want to know how to redirect site visitors to a landing page like Facebook – with login and registration on the page – while still having some select content available to them.

Look no further folks. Today, we’re gonna git ‘er done!

WordPress Buddypress - How to Make a Members Only Website (1)Once we’re finished with this project, and depending on your chosen theme of course, your landing page should look quite similar to the screenshot at right.

To make this WordPress-Buddypress project as easy as pie for even the most novice among us, this tutorial is divided into 5 parts so you can get stuff done at your leisure:

  1. Custom page template
    We need a custom page template to display the content we want site visitors to see.
  2. Landing page
    We’ll build our landing page with on-page login and registration.
  3. Logged-out menu
    We’ll create a special custom menu for site visitors.
  4. Redirect function
    We’ll write a custom function to ensure visitors can only access our selected content.
  5. Make stuff look good
    We’ll add a few style rules and tweak some stuff to get your new landing page and logged-out pages looking sharp as tacks!

Ready? Let’s dig in!

1) Custom page template

First of all, before making any of the changes described in this tutorial, I highly recommend that you be using a child-theme. If you’re not, and you’re not sure how to create one, see http://codex.wordpress.org/Child_Themes and What are Parent and Child Themes?

To make the custom template we need for visitor content, open a new document in your favorite text editor. (Do not use a word-processing program like MS-Word for this as it includes additional text formatting that will render your code useless. My +1 recommended text editor is Notepad++.)

Copy the entire contents of your theme’s page.php file to your new document. Then, insert the following code at the top, above everything else (be sure there isn’t a blank line at the top or you’ll wind up with the dreaded “Headers not sent” error when you try to use the template).

<?php
/*
Template Name: Custom Lockdown
*/
?>

Depending on the theme you are using for your WordPress-Buddypress site, there may be a lot of code in there, but your template should look something like this:

<?php
/*
Template Name: Custom Lockdown
*/
?>

<?php get_header(); ?>

/*
A lot of code in here
*/

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Since we don’t want site visitors to have access to any content other than the pages we choose, let’s make it so the sidebar and footer only display when logged-in. We’ll simply wrap the sidebar and footer calls in a is_user_logged_in() conditional, so your template will now look like this:

<?php
/*
Template Name: Custom Lockdown
*/
?>

<?php get_header(); ?>

/*
A lot of code in here
*/

<?php if (is_user_logged_in()) :?>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
<?php endif; ?>

If, for whatever reason you may have, you prefer to display the sidebar and footer even when logged-out, simply omit the previous step. Remember that if you do, visitors will be enticed to click on links in displayed widgets, and may get frustrated by being constantly redirected to your landing page. (Then again, you could always install a plugin to allow you to control which widgets appear when logged-in and logged-out. See this post for 10 such plugins.)

Save your new document as template-custom-lockdown.php. If you don’t like the template name I’ve suggested, simply change it to something you think is more appropriate. Remember to change the filename too though! Upload your new template to the root folder of your active child-theme.

You should now determine which pages are the only ones you want your site visitors to see. Here are some suggestions (they may not apply to your site):

  • About Us
  • Privacy Policy
  • Terms of Use
  • Membership Options
  • Features
  • Our Mission
  • …etc

In your WordPress website’s admin panel, go to “All Pages”. For each page you have selected, click the “Quick Edit” link, select your new Custom Lockdown template in the “Template” drop down menu and click “Update”. You can also use the “Bulk Edit” feature if you prefer.

Once we finish with part 4, those pages will be the only site pages logged-out visitors will have access to on your WordPress-Buddypress site. Of course, they will also have access to register.php, activate.php and wp-login.php. Oh, but wait, we need them to have access to the landing page too, right? Let’s build that now.

2) Landing page

Here’s where we take advantage of the flexibility of Buddypress components that use WordPress pages. Start by creating a new page to use as your landing page. Give it a welcoming title – maybe something like “Welcome” – add a nice image and a bit of introductory text, and click “Publish”. You do not need to assign the custom lockdown template you made in the previous step (you’ll see why in a bit). The URL for your landing page will be something like this for site visitors: yoursite.com/welcome

In your WordPress admin, go to your Buddypress settings and select the “Pages” tab. From the “Register” page dropdown, select the page you just created and click “Save”. You have now just told your WordPress-Buddypress installation that the page you created is to be used for registration. That takes care of getting the registration form to display on your landing page. Now let’s get everything else to display on that page too.

Copy the Buddypress “registration” folder from your parent theme to your child-theme. From the folder you just copied to your child-theme, open register.php. That is the template that will contain and display all your landing page content. I strongly recommend that you make a backup copy of that file, so just in case things go a bit haywire, you’ll have something to fall back on. You can call it backup-register.php and save it in the same folder.

Update: if your theme does not have a registration folder, please see this comment below.

As we want our landing page to have a similar layout as pages using the custom template we made earlier, remove the following Buddypress code from your child-theme’s register.php file. Remember to remove the corresponding closing div tags near the end of the file too, or things will go haywire!

<div id="content">
<div class="padder">

Next, we want to get the landing page content (your nice image and intro text), the login form, and the “Lost Password” link in there. We’ll be wrapping each of these elements in div containers so we can style ’em later on. We also want to put the signup form in a special div container so we can style that too. (If you do not want your users to be able to reset their passwords with the built-in WordPress function, simply omit the entire line where you see wp_lostpassword_url.) Add the following code just above where you see <form action=””. Then add a closing </div> tag just after the closing </form> tag.

<div id="my-custom-home">
<?php the_post(); ?>
<?php get_template_part( 'content', 'page' );?>
</div>

<div id="my-custom-login">
<h2><?php _e( 'Login Here', 'buddypress' ) ?></h2>
<?php wp_login_form(); ?>
<a href="<?php echo wp_lostpassword_url( get_permalink() ); ?>" title="Lost Password">Lost Your Password?</a>
</div>
<div id="my-custom-registration">

Note that the code above applies to more recent themes that use template parts. If your theme does not use template parts, see the comments below for an easy solution.

The last thing we want to do in register.php is hide the sidebar and footer like we did in our custom template. Replace the calls to the sidebar and footer with the respective code bits below. Again, if you don’t want to, don’t.

<<?php if (is_user_logged_in()) :?>
<?php get_sidebar( 'buddypress' ) ?>
<?php endif; ?>
<?php if (is_user_logged_in()) :?>
<?php get_footer( 'buddypress' ) ?>
<?php endif; ?>

Save the register.php file and upload it to the registration folder of your child-theme.

Great stuff! We now have our landing page set up with login and registration forms on the page, and a bit of introductory content to boot. We’ve also selected the pages site visitors have access to, and have assigned our Custom Lockdown template to all of those.

Go ahead and test stuff out now to make sure it works properly before we go any further. Be sure you’re logged-out of your site, then navigate to your landing page url. Don’t worry about how it looks just yet. Let’s be sure all the functionality is there first. Done? Good.

FREE EBOOK
Your step-by-step roadmap to a profitable web dev business. From landing more clients to scaling like crazy.

By downloading this ebook I consent to occasionally receive emails from WPMU DEV.
We keep your email 100% private and do not spam.

FREE EBOOK
Plan, build, and launch your next WP site without a hitch. Our checklist makes the process easy and repeatable.

By downloading this ebook I consent to occasionally receive emails from WPMU DEV.
We keep your email 100% private and do not spam.

3) Logged-out menu

Now let’s create a logged-out menu for your WordPress-Buddypress site with links to all logged-out-authorized pages only. We need to do only 2 things to create the new menu:

  • register the new menu in your child-theme’s functions.php file
  • call the new menu in the right spot, and under the right conditions, in the child-theme’s header.php file

Open your child-theme’s functions.php file now. If it doesn’t have one yet, create it now (see this page for more on this file in child-themes).

Now open your parent theme’s functions.php file and locate the function that has register_nav_menu in it. It will look something like this:

if ( ! function_exists( 'theme_register_menus' ) ) :
function theme_register_menus() {
	register_nav_menu('top_menu', __('Top Menu', TEMPLATE_DOMAIN));
}
endif;

Copy that entire function to your child-theme’s functions.php file. Now copy the line that has register_nav_menu in it, and paste it directly beneath that line. You should have 2 identical lines, one after the other. In one of them – it doesn’t matter which one – change both occurrences of the name of the menu to something you’ll recognize as your logged-out menu (remember to separate words in the 1st occurrence with underscores). Perhaps simply call it Logged-Out Top Menu. Your function should now look something like this:

if ( ! function_exists( 'theme_register_menus' ) ) :
function theme_register_menus() {
	register_nav_menu('top_menu', __('Top Menu', TEMPLATE_DOMAIN));
	register_nav_menu('logged_out_top_menu', __('Logged Out Top Menu', TEMPLATE_DOMAIN));
}
endif;

Save your functions.php file and upload it to the root of your child-theme. You now have 2 different menus registered in your child-theme. As we are declaring the same function that exists in the parent-theme, it replaces that function (which is why we register the original menu again in the child-theme). If you visit Appearance > Menus in your site’s backend, you’ll see in the Theme Locations box at top-left that Your theme supports 2 menus. See it? Great!

While you’re there, you may as well take a moment to create your new logged-out menu (we’ll get it to display in a moment). Create a new menu and add all the pages you had earlier assigned your Custom Lockdown template to. Also add the page you had earlier assigned for registration in your Buddypress settings – i.e.: your landing page. You may want to give that one an easy-to-recognize navigation label, like Login or Signup. Save your menu, select it for your logged-out menu in the Theme Locations box, and save there too.

Now we want to get that new menu to appear in the right spot in the header, but only display when logged-out. In other words, our new menu will appear when logged-out (your original menu will not be called), and it will be replaced by your original menu when logged-in.

Open your child-theme’s header.php file. If it doesn’t exist yet in your child-theme, simply copy the one from the parent to the child. Search your child-theme’s header.php until you find the call for wp_nav_menu. It will look something like either example below:

<?php wp_nav_menu( array(
	'theme_location' => 'top_menu',
	'menu_class' => 'topmenu',
	'container' => '',
	'fallback_cb' => 'theme_fallback_menu'
)); ?>
<?php wp_nav_menu( array('theme_location' => 'top_menu', 'menu_class' => 'topmenu', 'container' => '', 'fallback_cb' => 'theme_fallback_menu')); ?>

Copy that entire snippet and paste it directly beneath so you have 2 identical snippets, one on top of the other. The only thing we want to change here is the value for theme_location in the 2nd one. Locate that value in the 2nd snippet, and replace it with the value we gave to the new menu we created above. In the above example, we called it logged_out_top_menu.

Now we’re going to wrap those 2 menu calls in a conditional so that the 1st one appears only when logged-in, and the 2nd appears only when logged-out. Paste the following code before the 1st menu call:

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

Then add this between the 2 calls:

<?php else: ?>

Finally, add the following after the 2nd menu call:

<?php endif; ?>

Your entire code for both menu calls should now look something like this example:

<?php if (is_user_logged_in()) :?>
	<?php wp_nav_menu( array(
		'theme_location' => 'top_menu',
		'menu_class' => 'topmenu',
		'container' => '',
		'fallback_cb' => 'theme_fallback_menu'
	)); ?&gt
<?php else: ?>
	<?php wp_nav_menu( array(
		'theme_location' => 'logged_out_top_menu',
		'menu_class' => 'topmenu',
		'container' => '',
		'fallback_cb' => 'theme_fallback_menu'
	)); ?&gt
<?php endif; ?>

We have now registered both a logged-in and a logged-out menu in the child-theme’s functions.php file, have created the new logged-out menu in our site’s backend, and have set up the header.php file so that each menu appears only when the correct condition is met.

4) Redirect function

Now it’s time to create the function that will ensure that site visitors – i.e.: logged-out – will be able to access only the pages we have added to our new logged_out_top_menu, our landing page (register.php), as well as activate.php and wp-login.php (for password recovery).

Open your child-theme’s functions.php file again. Paste the following code directly after the opening <?php tag:

add_action( 'wp', 'custom_lockdown_redirect', 3 );
function custom_lockdown_redirect(){
global $wp;
	if (!is_user_logged_in()){
	if ( bp_is_activation_page()
		|| bp_is_register_page()
		|| is_page_template( 'template-custom-lockdown.php' )
		|| ( in_array( $GLOBALS['pagenow'], array( 'wp-login.php' )))
		)
	 return;
		bp_core_redirect(get_option('siteurl') . "/welcome");
		exit;
		}
	}

If you have used the example filename I gave above for the Custom Lockdown template (template-custom-lockdown.php), and the example page slug for the landing page (welcome), the redirect function will work as-is. If you have changed those in any way, you will need to edit the above function so it contains the proper names.

Once you have edited the function with your file and page names (if necessary), save your functions.php file and upload it again to your child-theme. To test the function, be sure you’re logged-out of your site. If you’re already logged-out, simply refresh the page (you may need to clear your browser’s cache also). If all is well, you should see only your logged-out menu appear in your site’s header.

Click each link to be sure you can get to it when logged-out. Now try to get to any other page or url on your site. You should be redirected to your new landing page. Fun, huh?

5) Make stuff look good

Now for the final bit: let’s add a bit of simple css magic to make your WordPress-Buddypress landing page look snappy! If you have used the example names I gave for the wrapper divs in part 2 (Landing page), the following css will pop your landing page right into shape. Add the following to your child-theme’s style.css file. (If you’re using a theme from WPMUdev.org, you’ll likely want to edit the _inc/css/child-style.css file instead.)

/*LANDING PAGE*/
#my-custom-home {
  float:left;
  }
#my-custom-home .post-body img{
  max-height:212px;
  width:auto;
  }
#my-custom-home h1.post-title, #my-custom-home .post-meta {
  display:none;
  }
#my-custom-login {
  float:right;
  background:#eee;
  padding:1em;
  }
#my-custom-registration {
  float:left;
  width:100%;
  }
#my-custom-registration h2 {
  background:#eee;
  margin:2em 0 0.5em;
  padding:0.5em;
  }

WordPress Buddypress - How to Make a Members Only Website (1)Save your style.css file and upload it to your child-theme. Now, still logged-out of your site, refresh your landing page and everything should pop right into shape as in the example image at the top of this page. Here it is again just for convenience.

If you’re using a responsive theme, you may want to tweak things a bit to get the landing page looking all nice and pretty on smaller devices. If you’re not sure how to write specific style rules for various devices and capabilities, check out this great article from SmashingMagazine.com, or search Google for how to use css media queries.


I hope you enjoyed this tutorial on building a members-only WordPress-Buddypress site, and find use for it! If you need any help with any part of it, or want to show off the results of your efforts, please leave a detailed comment below (with a link to your site if possible). Thanks for reading!

Photo credit: Flickr.com