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');
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.