wp query – WP_Query: how to sort all posts by date when one category has a custom “date” field?

Question

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

0
cmlb 2 months 2023-09-28T12:24:50-05:00 0 Answers 0 views 0

Leave an answer

Browse
Browse