0

I want to hide some posts from feeds, searches and nearly everything, apart from URL to this post. To have so called archive. Private post is also not an option because unlogged users with URL should see it as well.

I've used the WP hide posts plugin but it made very heavy load for my site (I have around 60-70 loads per minute) I would like to make custom function, but I am not very comfortable with WordPress API and functions. But as far as I've read codex the pre_get_posts would make it happen before query would have been formed, so it shouldn't make such a heavy load as far as I understand this.

Here is the part I need your help to ensure me that I am going into right direction.

So the first part with adding meta data to posts from category should be ok right? but I can't figure out how to connect it with pre_get_posts function, I've pasted functions from codex to exclude posts from search results and from home page.

//adding value hidden to category 'archive'
<?php
add_action('wp_insert_post', 'my_add_custom_fields');
function my_add_custom_fields($post_id)
{
    if(in_category( $archive)){
        if ( $_POST['post_type'] == 'your_post_type' ) {
            add_post_meta($post_id, 'hidden', '1', true);
        }
}
    return true;
}
?>

//filtering out posts with meta key 'hidden' and value '1'


<?php add_action( 'pre_get_posts', 'your_function_name' ); ?>

function search_filter($query) {
  if ( !is_admin() && $query->is_main_query() ) {
    if ($query->is_search) {
      $query->set('post_type', 'post');
    }
  }
}

add_action('pre_get_posts','search_filter');function exclude_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '-1,-1347' );
    }
}
add_action( 'pre_get_posts', 'exclude_category' );

function exclude_category( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'cat', '-1,-1347' );
    }
}
add_action( 'pre_get_posts', 'exclude_category' );
  • apart from URL to this post. What does this mean? – Brad Dalton May 15 '15 at 11:33
  • which part, please be more specific? – niziou May 15 '15 at 12:06
0

I'm not sure how your current "hidden" checkbox code is working (there's an undefined $archive variable, in_category might not fire correctly in the context, and I doubt your post type is actually your_post_type).

Just to make sure we get everything working, here is a complete solution for adding a checkbox to the edit post screen, where you can toggle it's "hidden" state correctly:

/**
 * Register our meta box that will show the "hide this post" checkbox.
 */
function wpse_188443_add_hidden_meta_box( $post_type ) {
    $hidden_types = array(
        'post',
        // Add any other post types you need to hide
    );

    if ( in_array( $post_type, $hidden_types ) ) {
        add_meta_box(
            'wpse_188443_hidden',
            'Hide Post From Archives',
            'wpse_188443_hidden_meta_box',
            $post_type,
            'side' /* Either "advanced", "normal" or "side" */
        );
    }
}

add_action( 'add_meta_boxes', 'wpse_188443_add_hidden_meta_box' );

/**
 * Display our meta box.
 */
function wpse_188443_hidden_meta_box( $post ) {
    $is_hidden = !! get_post_meta( $post->ID, '_hidden', true );
    ?>

<label>
    <input type="checkbox" name="wpse_188443_hidden" <?php checked( $is_hidden ) ?> />
    Hide this post from archives
</label>

<!-- A hidden input so that we only update our checkbox state when this field exists in $_POST -->
<input type="hidden" name="wpse_188443_hidden_save" value="1" />

<?php
}

/**
 * Save our checkbox state.
 */
function wpse_188443_hidden_save( $post_id ) {
    if ( isset( $_POST['wpse_188443_hidden_save'] ) ) {
        if ( isset( $_POST['wpse_188443_hidden'] ) )
            update_post_meta( $post_id, '_hidden', '1' );
        else
            delete_post_meta( $post_id, '_hidden' );
    }
}

add_action( 'wp_insert_post', 'wpse_188443_hidden_save' );

Read more in this answer for an explanation of the technique used above.

And now for actually hiding the "hidden" posts, it should be as simple as:

function wpse_188443_hidden_posts( $wp_query ) {
    if ( ! is_admin() && $wp_query->is_main_query() && ! $wp_query->is_singular() ) {
        if ( ! $meta_query = $wp_query->get( 'meta_query' ) )
            $meta_query = array();

        $meta_query[] = array(
            'key'     => '_hidden',
            'value'   => '',
            'compare' => 'NOT EXISTS',
        );

        $wp_query->set( 'meta_query', $meta_query );
    }
}

add_action( 'pre_get_posts', 'wpse_188443_hidden_posts' );
|improve this answer|||||
  • Thanks but I wasn't specific enought, I wanted to hide every post from custom, made by myself category which I have called Archive. So it would be imposible to enter throught tag/category/menu/search result, Your code is very good I've already implemented it, but I still see this posts even tho the checkbox is checked. EDIT: actually I was too hasty, the post is hidden from search results, tho when I'm in post I can still navigate to whole category inside by clicking the tag above post. Thanks for your help I'll try to change it by myself :) – niziou May 15 '15 at 12:30
  • So do you want to hide a custom post type, a post in a certain category, or both? We need to be clear about the terminology otherwise we'll end up with another lengthy answer that doesn't address the problem. – TheDeadMedic May 15 '15 at 12:33
  • Nah it address answer :) I will figure it out by mysefl from this point. Thanks for you help. And just to be clear. I wanted to hide "Archive" category (which I've created, so no WordPress archive page or so.) from everywhere apart from URL access :) – niziou May 15 '15 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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