How to hide a post from archives

I want to hide the WordPress post from archives page using the ‘private’ option. I only want the post to be hidden from archives but visible to public. How to I do it?

Related posts

2 comments

  1. You’ll want to filter the main query via pre_get_posts callback.

    If you’ll only want to handle one specific post in this manner, you can reference/exclude its post ID directly. If, however, you want this same behavior for any future private posts, then I would query all posts with $post->post_status of private, and exclude them.

    One post (where ID = 123):

    function wpse99672_filter_pre_get_posts( $query ) {
        if ( ! is_singular() && $query->is_main_query() ) {
            $query->set( 'post__not_in', array( 123 ) );
        }
    }
    add_action( 'pre_get_posts', 'wpse99672_filter_pre_get_posts' );
    

    Or, for all private posts:

    function wpse99672_filter_pre_get_posts( $query ) {
        if ( ! is_singular() && $query->is_main_query() ) {
            // Query all post objects for private posts
            $private_posts = new WP_Query( array( 'post_status' => 'private' ) );
            // Extract post IDs
            // Note: for performance, you could consider
            // adding this array to a transient
            $private_post_ids = array();
            foreach ( $private_posts as $obj ) {
                $private_post_ids[] = $obj->ID;
            }
            $query->set( 'post__not_in', $private_post_ids );
        }
    }
    add_action( 'pre_get_posts', 'wpse99672_filter_pre_get_posts' );
    
  2. I think the easiest way would be to control the loop in the archive.php file, IF it’s just the one post you want to hide from the archives.

    $query = new WP_Query( 'p=-7' );
    

    Where 7 is the post_ID of the post you want to hide and the - sign designates you want to exclude it from the loop.

    Take a look at this link that explains the usage and arguments that can be passed, in case you want to go further then what your question suggests.

    Here and here you can find alternate methods to accomplish what I mentioned.

    — Update —

    Given toscho’s comments I’ve dug around a bit and here is how you can use a filter on the pre_get_posts():

    function exclude_post( $query ) {
        if ( is_archive() ) {
            $query->set( 'p', -7 );
            return;
        }//end if
    }//end function
    add_action( 'pre_get_posts', 'exclude_post' );
    

Comments are closed.