wp query – WP_Query: how to sort all posts by date when one category has a custom “date” field?
We have a couple of hundred posts that are spread across 4 or 5 categories and so far we’ve been just fine with sorting by publish date. We recently added an “Event” category that has a custom “date” field, and when viewing all posts we want all non-events to be ordered by publish date but have the events within that same list showing up where the custom date determines.
I think this calls for a complex/nested meta_query
but I’ve never used one before and I’m having a hard time figuring it out. Here’s the relevant code:
<?php
$selected_category = isset( $_GET['category'] ) ? $_GET['category'] : '';
$selected_tag = isset( $_GET['tag'] ) ? $_GET['tag'] : '';
$past_state = isset( $_GET['past'] ) ? $_GET['past'] : '';
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$today = date( 'Ymd' );
$meta_query = null;
if ( !empty( $selected_category ) && !empty( $selected_tag ) ) {
$tax_query = array();
} else {
$tax_query = null;
}
if ( !empty( $selected_category ) ) {
$tax_query[] = array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $selected_category
);
}
if ( !empty( $selected_tag ) ) {
$tax_query[] = array(
'taxonomy' => 'post_tag',
'field' => 'slug',
'terms' => $selected_tag
);
}
if ( $selected_category === 'events' ) {
if ( !empty( $past_state ) ) {
$meta_query = array( array (
'key' => 'date',
'compare' => '<=', // past
'value' => $today
) );
} else {
$meta_query = array( array (
'key' => 'date',
'compare' => '>=', // upcoming
'value' => $today
) );
}
}
if ( $selected_category == 'events' ) {
if ( !empty( $past_state ) ) {
$args = array(
'post_type' => 'post',
'posts_per_page' => 9,
'paged' => $paged,
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'orderby' => 'meta_value',
'meta_key' => 'date',
'order' => 'DESC'
);
} else {
$args = array(
'post_type' => 'post',
'posts_per_page' => 9,
'paged' => $paged,
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'orderby' => 'meta_value',
'meta_key' => 'date',
'order' => 'ASC'
);
}
} else {
$args = array(
'post_type' => 'post',
'posts_per_page' => 9,
'paged' => $paged,
'meta_query' => $meta_query,
'tax_query' => $tax_query,
'orderby' => 'meta_value'
);
}
$query = new WP_Query( $args );
?>
To break it down the user clicks on some simple navigation links to select a category, which refreshed the page with the updated URL and then the query picks up on the filtering. What I think needs to happen is I need to add an else
to the if ( $selected_category === 'events' )
statement and concoct some sort of $meta_query there.
I tried adding something like this but I basically can’t figure out how to make the key optional if that makes any sense:
if ( $selected_category === 'events' ) {
...
} else {
$meta_query = array(
array(
'key' => 'date',
'compare' => 'EXISTS'
)
);
}
Leave an answer