I have filter the results like this and working: https://test.qualitybusinessawards.com/search?city=Chicago
If i want to filter like this City & Category is not working properly: https://test.qualitybusinessawards.com/search?city=Chicago&category=Dentist Here appear all Dentist but i want to appear only Dentist from Chicago.
I have created with this function:
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'event' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post' ) {
// allow the url to alter the query
$city = isset($_GET['city']);
$category = isset($_GET['category']);
if( $city ) {
$query->set('meta_key', 'city');
$query->set('meta_value', $_GET['city']);
}
if( $category ) {
$query->set('meta_key', 'category', '=');
$query->set('meta_value', $_GET['category']);
}
}
// return
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');
I have try to make lot of changes in this code but is not working....
This is not tested.
I think your problem is that you are trying to set multiple meta queries, but you are not nesting each meta query inside the meta_query
array.
You are currently just setting these meta queries in the main the query args and hoping for the best.
Nope, aint guna work my man. You need to imagine you are writing a WP_Query args array with Custom Field (post meta) Parameters
Skip to Display posts from several custom fields example (in link above).
The above Wordpress docs example shows correct usage of building your args array for WP_Query
, see below...
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'color',
'value' => 'blue',
'compare' => 'NOT LIKE',
),
array(
'key' => 'price',
'value' => array( 20, 100 ),
'type' => 'numeric',
'compare' => 'BETWEEN',
),
),
);
$query = new WP_Query( $args );
So lets remove all the meta_query
params from the above query $args
array, and lets pretend the below args is your my_pre_get_posts
passed $query
parameter...
$query = array(
'post_type' => 'product'
);
OK, all is well, until you try and $query->set
your meta values in your current question code. If $city
and $category
are true... here is the args you will be left with...
$query = array(
'post_type' => 'product',
'meta_key' => 'city',
'meta_value', 'Chicago',
'meta_key' => 'category',
'meta_value', 'Dentist'
);
$query
does not look good, right! This will bomb out as you are trying to use a single meta query twice in your query args!
You need to combine multiple meta queries into one array like this...
$query = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'city',
'value' => 'Chicago',
'compare' => '='
),
array(
'key' => 'category',
'value' => 'Dentist',
'compare' => '='
),
)
);
So in order to fix your question code is to pre build a $meta_query
array variable prior to using $query->set()
...
See your original code below, modified and fixed in example code below... (not tested)
function my_pre_get_posts( $query ) {
// do not modify queries in the admin
if( is_admin() ) {
return $query;
}
// only modify queries for 'event' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post' ) {
// check url params using gets
$city = isset($_GET['city']);
$category = isset($_GET['category']);
// set empty meta query array var but get any existing meta query params
$meta_query = (array)$query->get('meta_query');
// if city url param is set
if($city) {
// add city meta query array to main meta_query array
$meta_query[] = [
'key' => 'city',
'value' => $city,
'compare' => '='
];
}
// if category url param is set
if($category) {
// add category meta query array to main meta_query array
$meta_query[] = [
'key' => 'category',
'value' => $category,
'compare' => '='
];
}
// then the magic happens here by setting all the above `$meta_query` array using `set()`
$query->set('meta_query', $meta_query);
}
// boom then return...
return $query;
}
// pre get post action function call
add_action('pre_get_posts', 'my_pre_get_posts');