WordPress – Merging two complex queries into one

I have two fairly complex WordPress queries that I need to combine into a single query.

In my first query, I am getting WordPress Posts by the date they are published. Each day of posts is contained inside a container, with the date showed above the posts as a title. It also only hides any posts that are in the past. Only posts from today or the future are shown.

Read More

In my second query, I am getting WordPress Posts from a Custom Taxonomy. For each term in the taxonomy, posts are displayed inside a container utilizing the slug of that term as a class, and displaying the name of the term as the title.

What I need to accomplish and what I need help with, is as follows.

I need the first query exactly as it is now, however, in the first query, where it says “// Need code here to display posts by taxonomy term //”, I need to integrate the second query so that where posts are being output for that day, its also listing the posts by the term like in the second query.

Both queries function perfectly on their own, but I am having trouble with implementing a single query that utilizes the functionality from both queries to do what I need to do.

Here are my two queries:

1st Query:

<?php 
// First we get yesterdays date
$year = date("Y"); $month = date("m"); $yesterday = date("d", strtotime("-1 day"));
// Then we construct a query to get items from the calendar, either published or scheduled for a future date so that they appear on the calendar. We use date query to hide events that have already passed by querying after the date we got before. We use yesterdays date to ensure that TODAYS post are still obtained
$query = new WP_Query(array('post_type' => 'calendar',
    'post_status' => 'publish,future',
    'orderby' => 'post_date',
    'order' => 'DESC',
    'date_query' => array(
        array('after' => array(
                'year'  => $year,
                'month' => $month,
                'day'   => $yesterday
            )
        )
     )
 )); 
// This is a special loop that gets posts by day and encases each days worth of posts in a container and shows the date of those posts. jQuery will be applied to this
if ($query->have_posts()) {
    echo '<div class="day-posts">';
    while ($query->have_posts()) {
        $query->the_post();
        echo '<div class="day">';
        the_date('l jS F Y', '<div class="title"><div>', '</div>'); //Formats date, before echo, after echo
        echo '<div class="posts clearfix">';
        echo '<div class="post">';
        the_title('<div class="title">', '</div>');
        echo '<div class="content">';
        // Need custom code here to display posts by taxonomy //
        the_content();
        echo '</div></div></div></div>';
    }
    echo '</div>';
}?>

2nd Query:

<?php
$post_type = array('calendar');
$tax = 'event-category';
$tax_terms = get_terms($tax, array('orderby' => 'id', 'order' => 'ASC'));
if ($tax_terms) {
    foreach ($tax_terms as $tax_term) {
        $args = array(
            'post_type' => $post_type,
            "$tax" => $tax_term->slug,
            'post_status' => 'publish',
            'posts_per_page' => - 1,
            'caller_get_posts' => 1
            ); // END $args
        $my_query = null;
        $my_query = new WP_Query($args);
        if ($my_query->have_posts()) {
            echo '<div class="' . $tax_term->slug . '">';
            echo '<div class="title">' . $tax_term->name . '</div>;
            while ($my_query->have_posts()) : $my_query->the_post();
?>

<?php the_title();?>
<?php the_content();?>

<?php endwhile; echo '</div>'; } wp_reset_query(); }  } ?>

I hope I have done a good job of explaining what I am trying to do. If I have not, or there are questions, please ask and I’ll answer as quick as I can.

Related posts

Leave a Reply

1 comment

  1. Ok here you go (I dont have posts setup like your query so i didn’t test it but i believe this what you are looking for):

    // Setup the basic structure:
    $args = array(
        'post_type' => 'calendar',
        'post_status' => 'publish,future',
        'orderby' => 'post_date',
        'order' => 'DESC',
        'date_query' => array(
            array(
                'after' => array(
                    'year'  => $year,
                    'month' => $month,
                    'day'   => $yesterday
                )
            )
        ),
        'posts_per_page' => -1,
        'caller_get_posts' => 1
    );
    
    // For dynamic taxonomy term create a bootstrap tax_query
    
    $tax = 'event-category';
    $tax_terms = get_terms($tax, array('orderby' => 'id', 'order' => 'ASC'));
    if ($tax_terms) {
    
        $args['tax_query'] = array(
            array(
                'taxonomy' => $tax,
                'field' => 'slug',
            )
        );
    
        // Append the slugs to the tax_query terms
        foreach ($tax_terms as $tax_term) {
            $args['tax_query'][0]['terms'][] = $tax_term->slug;
        }
    }
    
    // Your One and only QUERY
    $my_query = new WP_Query($args);
    

    For $tax_term->slug and $tax_term->name you could use get_the_terms() within the query loop like:

    $terms = get_the_terms($post->ID, $tax);
    $terms = array_slice($terms, 0);
    $term = $terms[0];
    
    echo $term->slug;
    echo $term->name;
    

    EDITED

    See code comments for explanation/clarification

    if ($query->have_posts()) {
        $_tax = false;
        $same_date = array(); // collection of same dates
        $same_date_bool = true; // determine previous post date exist
    
        echo '<div class="day-posts">';
        while ($query->have_posts()) {
            $query->the_post();
            $date = get_the_date('l jS F Y');
    
            $same_date_bool = true;
    
            // Checking if post is displayed from the current date
            // then this post should be appended inside to previous
            // opened div.day tag
            if (!empty($same_date) && in_array($date, $same_date)) {
                $same_date_bool = false;
            }
    
            // Collecting all dates
            $same_date[] = $date;
    
            // If post is not in same date
            // create new div element
    
            if ($same_date_bool) {
                echo '<div class="day">
                    <div class="title">';
                echo $date;
                echo '</div>';
            }
    
            // If post is not in same date
            // create new div element
    
            if ($same_date_bool) {
                echo '<div class="posts clearfix">';
            }
    
            echo '<div class="post">';
            the_title('<div class="title">', '</div>');
            echo '<div class="content">';
    
            $terms = get_the_terms($post->ID, $tax);
            // Note: I'm assuming your post will
            // always have single term
            $terms = array_slice($terms, 0);
            $term = $terms[0];
    
            if ($term) {
                $_tax = true;
                echo '<div class="' . $term->slug . '">';
                echo '<div class="title">' . $term->name . '</div>';
            }
    
            the_content();
    
            if ($_tax) {
                echo '</div>';
            }
    
            echo '</div></div>';
    
            // If post is in same date
            // append closing div element for previous "div.day" element
            if (!$same_date_bool) {
                echo '</div></div>';
            }
        }
    
        echo '</div>';
    }
    

    Hope this helps now. Also I have replaced the caller_get_posts with ignore_sticky_posts because caller_get_posts has been deprecated since v3.1