Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums Back End Using WP's pre_get_posts to exclude post with meta_key

  • This topic is empty.
Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #208877
    Steven
    Participant

    I’m attempting to use a pre_get_posts function to exclude “featured” posts.

    With the Advanced Custom Fields plugin I created a new true/false field called featured. This true/false field returns 1 if ticked, 0 if not.

    I’ve been browsing Stack Overflow for an answer, and the top answer to this question makes the most sense to me: http://wordpress.stackexchange.com/questions/72099/can-i-exclude-a-post-by-meta-key-using-pre-get-posts-function

    My code:

    # Do not display "featured" show in archive.
    function featured_show( $query ) {
      if( !is_admin() && $query->is_main_query() && is_post_type_archive( 'shows' ) ) {
        $meta_query = $query->get('meta_query');
        $meta_query[] = array(
          'key' => 'featured',
          'value' => '1',
          'compare' => '!=',
        );
        $query->set('meta_query', $meta_query);
      }
    }
    add_action( 'pre_get_posts', 'featured_show' );
    

    This code returns a 404. I’ve looked for similar questions/answers, but they all get out of hand, like this one: http://wordpress.stackexchange.com/questions/142370/exclude-post-by-custom-meta-with-pre-get-posts

    Is there something “obvious” that I’m completely missing?

    Thanks!

    #208893
    Alen
    Participant

    Hey @steven,

    The meta_query takes array of arrays if that makes sense.

    $query->set('meta_query', $meta_query);

    should be…

    $query->set( 'meta_query', array( $meta_query ) );

    Here’s complete code, tested on my end, and working… althought when I was setting my custom field to featured for some reason it didn’t work. Once I made my custom field more unique, it started working… so that might be one of your issues as well. You should always prefix your custom fields with theme name, or whatever you see fitting. So featured would become something like theme_cf_featured.

    function featured_show( $query ) {
      if( !is_admin() && $query->is_main_query() && is_post_type_archive( 'shows' ) ) {
        $current_meta = $query->get('meta_query');
        $custom_meta = array(
            'key' => 'featured',
            'type' => 'BINARY',
            'value' => '1',
            'compare' => '!='
        );
        $meta_query = $current_meta[] = $custom_meta;
        $query->set('meta_query', array($meta_query));
      }
    }
    add_action( 'pre_get_posts', 'featured_show' );
    
    #208962
    Steven
    Participant

    The “array of arrays” makes sense… because meta_query is itself an array inside the WP_Query object, right?

    For some reason I couldn’t get it to work though, even after making my custom field’s title more specific.

    I changed from using a toggling field like “featured” to simply excluding the post id of the post to ignore. I’ll be honest, I don’t like the idea of ignoring the fact that your suggestion didn’t work, because I’m guessing that hints at an underlying problem somewhere. But these posts won’t change, and there won’t be any new ones added, and it’s just this one post to ignore, so I don’t think it’s too clunky of a solution:

    function exclude_best_of_show( $query ) {
        if ( !is_admin() && $query->is_main_query() && is_post_type_archive( 'shows' ) ) {
            // Exclude post 680 "Best of Destination Small Town"
            // from shows index page.
            $query->set( 'post__not_in', array( '680' ) );
        }
    }
    add_action( 'pre_get_posts', 'exclude_best_of_show' );
    
    #250176
    Kevin deLeon
    Participant

    I know this post is over a year old…but I thought I’d chime in. Your final solution would break any other meta_queries using “post__not_in” if you happened to have any…I ran into this problem on my site.

    So it may be better to preserve that by doing something like:

    function exclude_best_of_show( $query ) {
        if ( !is_admin() && $query->is_main_query() && is_post_type_archive( 'shows' ) ) {
           // Get any post__not_in arrays already set
           $current_not_in_array = $query->get('post__not_in');
    
           // Merge them with your new array to exclude
           $new_post_not_in = array_merge($current_not_in_array, [680]);
    
           $query->set( 'post__not_in',  $new_post_not_in );
        }
    }
    add_action( 'pre_get_posts', 'exclude_best_of_show' );
    
Viewing 4 posts - 1 through 4 (of 4 total)
  • The forum ‘Back End’ is closed to new topics and replies.