Restricting Access to WordPress pages only after login

This post describes how you can modify the wp_list_pages() function of WordPress so that it lists normally hidden pages if the user is logged in (You can hide pages from the administrator panel, or more easily using the excellent Pagemash plugin). Thus you can restrict access to certain pages on your site unless the user is logged in. What is also great about this method is that since we modify the wp_list_pages function it also hides these restricted pages in the navigation bar/ pages widget of  your site (Assuming they generate the list using wp_list_pages, which is usually the case). The wp_list_pages function is in the file post-template.php which can be found in the wp-include folder of your WordPress installation. Rename the current file as post-template-old.php or something similar in case something goes wrong.

Now all you have to do is open the file and look for the following block of code:

// Allow plugins to filter an array of excluded pages

$r['exclude'] = implode(',', apply_filters('wp_list_pages_excludes', explode(',', $r['exclude'])));

What this code is doing is basically setting the exclude variable with a list of the page IDs of the pages listed as hidden in the administrator section of WordPress. What we want to do is modify this so that these pages are excluded (i.e. hidden) only if the viewer is someone who isn't logged in. If the person is logged in then we would like for all the hidden pages to be displayed. To do this replace this block of code with the following:

if (is_user_logged_in()) {

$r['exclude'] = '';


else {

$r['exclude'] = implode(',', apply_filters('wp_list_pages_excludes', explode(',', $r['exclude'])));


All we are doing is using the is_user_logged_in function to either set none of the pages to be excluded (for the case that the person is logged in) or we exclude the pages marked as 'hidden' from the sight of regular visitors. So to use this method to make pages only visible to logged in visitors you will want to hide all these pages. I would also recommend setting them as 'private' to prevent someone from guessing the page ID and accessing the restricted pages. I would highly recommend complementing this method with use of the Sidebar login widget. This widget creates a nice login panel in your sidebar. Once the user logs in, your newly reloaded page will automatically update the navigation bar and the page widget in your sidebar to list the previously restricted pages.

The main drawback here is that now you cannot have other pages that are hidden from logged in visitors. However it shouldn't be too hard to modify the if->else statements above to tailor it to your requirements. Please my knowledge of PHP is absolutely zero and I only figured this out because it required a very simple piece of code. Also, this technique obviously won't work with blog posts. However it shouldn't be too hard to make similar if->else statements in your PHP files so that some posts/post categories remain hidden from users who aren't logged in.

If there are any php-gurus out there who read this, please do chip in with some ideas on how you can extend this to do more complex stuff. I would be especially interested in how one might go about using a similar method to hide posts and categories from regular site visitors.

Edit - Turns out there is a plug-in for doing similar stuff called page-restrict. While it does restrict page access to logged in users it doesn't seem to hide these restricted pages from the view of visitors who are not logged in. Personally I'm not a big fan of letting users know what the title of the restricted pages are, and also having them know that I am intentionally excluding them from some content on my site.

8 thoughts on “Restricting Access to WordPress pages only after login

  1. This is the real way to do it and it works like a charm.

    I looked through dozens of forums and tried everything, and finally found the solution that worked at

    If you’re logged in and have the capability to view a private page, it shows up in the menu … otherwise the page is not visible in the menu.

    For those interested, the change is in wp-includes/post.php in the function get_pages() .. line 2077 in the file.

    Code: [Select]
    $query = “SELECT DISTINCT * FROM $wpdb->posts $join WHERE (post_type = ‘page’ AND post_status = ‘publish’) $where “;

    Modified (or added right after):
    Code: [Select]
    $query = “SELECT DISTINCT * FROM $wpdb->posts $join WHERE (post_type = ‘page’ AND ” . get_private_posts_cap_sql(‘page’) . “) $where “;
    I’m going to take a look at a nightly build from 2.7 and see if the fix is included.

  2. Role Scoper is a great plugin. I’m looking for the opposite solution. I would like to hide a page only AFTER someone logs in. The page I would like to hide is a welcome page for nonmembers. It’s set up now such that once someone has logged in, a home page for members appears (courtesy of Role Scoper), but the nonmember welcome page is still there. I’d like to make the nonmember welcome page disappear.

    Coding this is beyond me – does anyone have a code edit or recommended plugin?

  3. Role Scoper worked like a charm! I had been wrestling with how to hide the page tabs in my Members Only section. I installed Role Scoper, clicked one check mark, crossed my fingers and it worked fabulously!!!

  4. Hi, nice article! Thanks for the code tips.

    Recently i’ve created a plugin to simplify the access control to a singular content, you have a video here :

    it is free to download before 02/21/2011 so help youselves. Then it gets 15 euros starting price . If you would like to help me launch that plugin i share 50% of sell amount you have an affiliate subscribe link under the video,


  5. Hey,

    Thanks for the tip.

    I had done as stated in here but I still couldn’t restrict any pages or post.

    As for the page-restrict plugin, it only restrict posts but not page.
    It may stated it will but it does not as I had tried multiple times.

    Please help!

    Foong Ting

Leave a Reply

Your email address will not be published. Required fields are marked *