How can I make it so only members see post summaries on category pages? Currently only members can access them, but they still show up on category pages for non members.

Note: I now made a plugin for this, you can get it at: https://github.com/NerdOfLinux/MemberOnly

  • So you need all category views to be block or just one/few?
    – Cedon
    Commented Jul 23, 2017 at 2:04
  • I need for member only posts to not show up for non members. Commented Jul 23, 2017 at 2:05
  • So it's a single category called something like members-only?
    – Cedon
    Commented Jul 23, 2017 at 2:06
  • No, I have categories that I need both members and non members to access, I just want to hide some posts from non members. Commented Jul 23, 2017 at 2:07

3 Answers 3


I haven't had time to test this, but you can probably do this with the the_content filter hook. This way you won't have to insert this code into archive.php, category.php, tag.php, author.php and any other archive file depending on how your theme is structured.

In your theme's functions.php file add the following:

function my_filter( $content ) {

    $categories = array(

    if ( in_category( $categories ) ) {
        if ( is_logged_in() ) {
            return $content;
        } else {
            $content = '<p>Sorry, this post is only available to members</p>';
            return $content;
    } else {
        return $content;
add_filter( 'the_content', 'my_filter' );

So what this could should do is intercept the content of the post between when it's pulled from the database and it's displayed. Then it's going to check and see if the post has one of the categories listed in the $categories array (NOTE: It's best to use the category slug here in the array). Then it will see if the user is logged in.

If they are, then it will display the post. If they are not, then it will set the content to the message and then send that back in place of the post's content.

If the user is logged in, or the post is not in any of those categories in the array, then it will return the post as normal.

NOTE: If you're using the_excerpt() in your theme instead of the_content(), then simply change the hook in the add_filter() call to 'the_excerpt' and it should work.

  • I added it to my functions.php file, but it still isn't working. I changed is_logged_in to is_user_logged_in because that was what I found in the wordpress documentation. I tried both the_excerpt and the_content. I'm, using the twenty seventeen theme by the way. Commented Jul 23, 2017 at 3:03
  • I fixed it. Just change is_category to in_category. From: stackoverflow.com/questions/2515732/… Commented Jul 23, 2017 at 6:14
  • Sorry about the function typos. Thanks for catching and fixing them.
    – Cedon
    Commented Jul 23, 2017 at 11:18

For this kind of thing, I prefer to work within templates rather than in functions.php. This way, you don't need an additional if statement to determine what category you are applying the conditions to. You can apply this method to all categories using the category.php template or create custom templates for individual categories if you want to display different content in different categories. Personally, I find using templates for this kind of work makes it easier see what I'm doing.

In your case, you wou create an if statement like the example above with the is_user_logged_in tag before whatever your want to reveal to your members. Then add an else for whatever you want to display instead when a user is not logged in before closing the statement.

<?php if ( is_user_logged_in() ) { 
    the_excerpt(); // or whatever
} else {
    echo '<p>This information is for members only.</p>'; // or whatever 
  • The problem with working in the template files themselves is that he would need to insert the code multiple times depending on how his theme is structured. If he only had archive.php then it would be fine, but he'd have the same problem again if there were tags.php, 'author.php`, etc. Using the filter would catch it everywhere.
    – Cedon
    Commented Jul 23, 2017 at 11:20
  • Yes, I'm sure there are advantages and disadvantages to each method. It seemed the OP was having difficulty implementing your solution, so I suggested another approach that might be easier him/her.
    – dooley
    Commented Jul 23, 2017 at 19:52
  • The solution I proposed would be more DRY is a separate loop was made and added to each template requiring it.
    – dooley
    Commented Jul 23, 2017 at 19:58
  • How is it DRY when you have to put it into every template file? The solution I proposed will occur on every template file. His difficulties came from typos I made and didn't catch.
    – Cedon
    Commented Jul 24, 2017 at 2:53
  • What I wrote about was making a separate loop, not adding that code to every template. By that I mean creating a separate file with that code in it and adding it to template files as needed with get_template_part. I apologize if I created any confusion.
    – dooley
    Commented Jul 24, 2017 at 17:53

You can use the post id's store them in an array and then display them one by one.

  <?php $thePostIdArray = array("28","74", "82", "92"); ?>
  <?php $limit = 4 ?>
  <?php if (have_posts()) : ?>
  <?php while (have_posts()) : the_post(); $counter++; ?>
  <?php if ( $counter < $limit + 1 ): ?>
  <div class="post" id="post-<?php the_ID(); ?>">
  <?php $post_id = $thePostIdArray[$counter-1]; ?>
  <?php $queried_post = get_post($post_id); ?>
  <h2><?php echo $queried_post->post_title; ?></h2>
  <?php endif; ?>
  <?php endwhile; ?>
  <?php endif; ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.