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!

Featured Plugin - WordPress Membership Site Plugin

If you're thinking about starting a paid, or just private, membership site then this is truly the plugin you've been looking for. Easy to use, massively configurable and ready to go out of the box!
Find out more

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.

Featured Plugin - WordPress Appointments Plugin

Take, set and manage appointments and client bookings without having to leave WordPress. Appointments+ makes it easy.
Find out more

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.

Featured Plugin - WordPress Facebook Plugin

Would you like to add Facebook comments, registration, 'Like' buttons and autoposting to your WP site? Well, The Ultimate Facebook plugin has got that all covered!
Find out more

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.

Featured Plugin - WordPress Q&A Site Plugin

It's now incredibly easy to start your own Q&A site using nothing more than WordPress - The Q&A plugin simply and brilliantly transforms any site, or page, into a perfect support or Q&A environment.
Find out more

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?

Featured Plugin - WordPress Google Maps Plugin

Simply insert google maps into posts, sidebars and pages - show directions, streetview, provide image overlays and do it all from a simple button and comprehensive widget.
Find out more

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

Featured Plugin - WordPress Ecommerce Shopping Cart Plugin

Out of all the WordPress ecommerce plugins available, MarketPress has got to be the winner - easy to configure, powerful functionality, multiple gateways and more. A simply brilliant plugin!
Find out more

Comments (202)

  1. And Patrick how to make login and sign up and lost your password button colourful like yours in kwitterz. And How to place Signup button in Right Corner or In the middle like yours please reply me fast.

  2. Hello Paterick Can you please reply me fast and can you please again send me command to keep my registration form in order because i have added some more option in it.

    THANKS IN ADVANCE

  3. Hello Patrick i have done everything in my site but i want your Help can you please tell me how can we add logo in simple market theme and second thing.
    My tab name is welcome how can i change it to Login or Signup instead f Welcome.

    Please Help me. My Site – Socialn.yzi.me

  4. I’ve been able to get most of this setup with one major problem. When trying to login from the landing page, rather than successfully logging in, the landing page reloads each time you hit the log in button. The user isn’t logged in and no error message is displayed.

    I’m thinking that there might be some issue where the follow on page that needs to load after logging in is being blocked by the custom template. Any idea why this might be happening?

  5. Thank you so much for your post – I’m very much a beginner and was able to figure this out. I’m down to the final step and hoping my question is an easy one.

    I’m using a frisco child theme and was one that had to use:

    in my register.php because there aren’t template parts.

    For some reason the CSS will not float this left…grrr.
    Here is the URL: http://itefboardportal.com/welcome/

    I’ve tried using the code inspector on my browser and just can’t seem to crack it.

    Any suggestions?

    • Hey there @Ashley

      Yep, to get floats to play nice, defining container widths helps. Adding width:68%; to #my-custom-home should do the trick.

      Also, you may want to reduce the width of #my-custom-registration to 95% in your theme, as the margin is adding to the overall width.

      Plus, as you have added margin:2em; to #my-custom-registration, you may want to remove the margin from the h2 heading to reduce that huge white-space above it. :)

      Finally, remember that your theme is responsive, so you’re gonna want to tweak at least some widths (maybe padding & margins too) for smaller screen sizes. Try adding this media query to your style-sheet for starters and adjust if required:

      @media only screen and (max-width: 767px) {
      #my-custom-home, #my-custom-registration {width:auto;}
      #my-custom-login {width:90%;}
      }

      I hope this helps!

  6. So when i went on my themes editor to look for a registration.php, I could not find one. The only thing I could find was just a buddypress.php and when I searched the actual plug-in, i couldn’t find one there either. I am using the Avada theme from ThemeFusion. Could it be because of my theme?
    I would really like to be able to do this and I can’t find any other support on the web!

  7. Tim,
    It might be easier for you to simply use some plugins.

    1-) Private Community For BP Lite, Makes BP pages private and only accessable to logged in users with the exception of the pages you set.

    http://wordpress.org/plugins/private-community-for-bp-lite/

    This will let you control which pages are visible to non-logged in users.

    2-) Menu Item Visibility Control, Control individual menu items’ visibility based on your desired condition.

    http://wordpress.org/plugins/menu-items-visibility-control/

    This will let you control which menu items are visible to users that are logged in, or not. It uses conditional logic, so if you are familiar with “widget logic” plug-in, this will be intuitive to you. If not, then it is easy enough to learn.

    I use these two plugins together to show specific pages and specific menus to non-logged in users that promote my site and encourage them to join. Once logged in then of course they can see all pages and menu items.

    Hope this helps.

    Cheers!
    Chris

  8. That is great advice, thank you! What would be the best way for me to go about making a landing page than with the registration form / log-in on it?
    I am not as concerned about blocking access to non-logged in users, but more about creating a landing page which they can sign up on / log-in without having to click around!

    Thank you!

  9. Hi there @tim_merithew

    Since BuddyPress 1.7, themes no longer need special templates included to be compatible. So it’s quite possible that your current theme doesn’t have it.

    If your theme does not have a registration folder with the register.php template in it, you can simply copy the folder from the default theme in your copy of BuddyPress.

    Browse to buddypress/bp-themes/bp-default/ and copy the registration folder from there into your theme (or child-theme if you’re using one).

    Once you have the register.php template open, be sure to inspect the HTML structure of templates from your theme, and that that structure is mirrored in register.php so the base layout of register.php will be just like any other page on your site.

Participate