2

The default search returns all post types, which is what I want. But for one specific custom post type I want to limit the result to a specific meta key value (a custom date that must be greater than today).

Using the pre_get_posts hook and setting the meta_query does get me the correct result for that post type, but it also filters out all post types that do not have that key set.

Is it possible to use the meta_query only for one specific cpt?

That should be clear enough but here's some code nonetheless:

function searchExcludeOldMatches($query) {
    if (!is_admin()&&$query->is_search) {
        $query->set('meta_query', array(
            array(
                'key' => 'cpt-match-date'
                ,'value' => date('Y/m/d',time())
                ,'type' => 'DATE'
                ,'compare' => '>'
            )
        ));
    };
    return $query;
};
add_filter('pre_get_posts','searchExcludeOldMatches');

2 Answers 2

2

This might not have worked before, but WordPress's meta queries now support the relation parameter. To complete what @s_ha_dum was looking to do, simply add the relation parameter (as OR) and add a second meta query for NOT EXISTS. Example:

function searchExcludeOldMatches( $query ) {
    //if we're on the admin panel, or it's a search, or it's not the post type we want to filter, return the original query
    if( is_admin() || !$query->is_search() || $query->get( 'post_type' ) != 'yourposttype' )
        return $query;

    //this is the query we want to update
    $query->set('meta_query', array(
        'relation' => 'OR',
        array(
            'key' => 'cpt-match-date'
            ,'value' => date('Y/m/d',time())
            ,'type' => 'DATE'
            ,'compare' => '>'
        ),
        array(
            'key' => 'cpt-match-date'
            ,'value' => date('Y/m/d',time())
            ,'type' => 'DATE'
            'compare' => 'NOT EXISTS'
        ),
    ));
    return $query;
}
add_filter('pre_get_posts','searchExcludeOldMatches');

For further reading, check out the WP Meta Query Codex Page: https://codex.wordpress.org/Class_Reference/WP_Meta_Query

Edit Nov 17, 2015: Added filter for custom post type and simplified the conditional statement.

2
  • How does this allow results from "all post types" but apply a restriction based on a meta key to only one post type? You appear to be doing exactly what the OP is trying to avoid: "Using the pre_get_posts hook and setting the meta_query does get me the correct result for that post type, but it also filters out all post types that do not have that key set."
    – s_ha_dum
    Nov 17, 2015 at 17:14
  • @s_ha_dum Good catch about the custom post type -- I forgot that filter in my comment as I copied some of my code from a production site into this and just updated the values to match your post. Now this meta query will only affect targted post types. But combining an "OR" relation with a "NOT EXISTS", you can get all posts of 'posttype' that either match a value, or do not have a value set, which is what I believe the OP is asking for.
    – Elly Post
    Nov 17, 2015 at 21:06
1

You can limit your query even further...

if (
  !is_admin() 
  && $query->is_search() 
  && ($query->get('post_type') == 'yourposttype')
) { 
  // ...

But if you want to query all post types but restrict those results for only one post type in the same query, you can't do that. You would need a UNION statement, probably, and WP_Query does not support that. You will need to use multiple queries or write your own SQL.

The easiest way to do it is something like this:

$post_ids = new WP_Query(array(
  // query for one post type
  'fields' => 'ids',
  // other parameters
));

$post_ids_2 = new WP_Query(array(
  // query for the others
  'fields' => 'ids',
  // other parameters
));
// join them
$post_ids = $post_ids->posts + $post_ids_2->posts;
$posts_qry = new WP_Query(array('post__in'=> $posts_ids));

But not the most efficient. That is three queries. I mention other possibilities in another thread: Custom query with category exclusion and post-meta "whitelist"

Related

https://wordpress.stackexchange.com/a/79977/21376

2
  • Why? I do not want to limit my search to one post type.
    – Sjeiti
    May 15, 2013 at 21:35
  • Ah ok... I feared it wasn't possible... I'll work my way around it then.
    – Sjeiti
    May 15, 2013 at 22:00

Your Answer

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

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