I'm trying to build a query to filter a list of employees by a location
taxonomy. Some staff are fixed, in that they'll only ever work out of a single office, but others are flexible and work from them all.
If a user chooses to filter by Office 1
, I want to display staff members assigned the Office 1
term for the location
taxonomy and staff members with no term set at all.
For brevity I've stripped back the code below to the basic principles. I tried to set up a tax_query
to query both the selected location
and any posts without one set, but suspect the logic is flawed - any advice would be massively appreciated.
<!-- <select> field for user to select location -->
<form method="get">
<select name="locations" id="locations">
<option value="location-1">Location 1</option>
<option value="location-2">Location 2</option>
<option value="location-3">Location 3</option>
<input type="submit">
</form>
// Target items by 'location' if option set in <select>
if(isset($_GET['locations'])) {
$location = sanitize_text_field( $_GET['locations'] );
$tax_query[] = array(
'relation' => 'AND',
array(
'taxonomy' => location,
'field' => 'name',
'terms' => $location,
'operator' => 'IN',
),
array(
'taxonomy' => location,
'operator' => 'NOT IN',
),
);
}
// Configure query args
$args = array(
'post_type' => 'staff',
'posts_per_page' => -1,
'tax_query' => $tax_query,
'order' => 'ASC',
'post_status' => 'publish'
);
I'm trying to build a query to filter a list of employees by a location
taxonomy. Some staff are fixed, in that they'll only ever work out of a single office, but others are flexible and work from them all.
If a user chooses to filter by Office 1
, I want to display staff members assigned the Office 1
term for the location
taxonomy and staff members with no term set at all.
For brevity I've stripped back the code below to the basic principles. I tried to set up a tax_query
to query both the selected location
and any posts without one set, but suspect the logic is flawed - any advice would be massively appreciated.
<!-- <select> field for user to select location -->
<form method="get">
<select name="locations" id="locations">
<option value="location-1">Location 1</option>
<option value="location-2">Location 2</option>
<option value="location-3">Location 3</option>
<input type="submit">
</form>
// Target items by 'location' if option set in <select>
if(isset($_GET['locations'])) {
$location = sanitize_text_field( $_GET['locations'] );
$tax_query[] = array(
'relation' => 'AND',
array(
'taxonomy' => location,
'field' => 'name',
'terms' => $location,
'operator' => 'IN',
),
array(
'taxonomy' => location,
'operator' => 'NOT IN',
),
);
}
// Configure query args
$args = array(
'post_type' => 'staff',
'posts_per_page' => -1,
'tax_query' => $tax_query,
'order' => 'ASC',
'post_status' => 'publish'
);
Share
Improve this question
edited Oct 12, 2020 at 19:09
Graeme Bryson
asked Oct 12, 2020 at 19:02
Graeme BrysonGraeme Bryson
291 silver badge11 bronze badges
1 Answer
Reset to default 1It's actually pretty simple: You'll want to use an OR
relation, and use the NOT EXISTS
operator for selecting posts that are not assigned to any terms in the specified taxonomy.
$tax_query[] = array(
'relation' => 'OR',
array(
'taxonomy' => 'location',
'field' => 'name',
'terms' => $location,
),
array(
'taxonomy' => 'location',
'operator' => 'NOT EXISTS',
),
);