skip to Main Content

I have the following:

$args = array(
    'post_type' => 'events',
    'posts_per_page'=> 6,
    'post_status'=> 'publish',          
        'meta_query' => array(
            'relation'   => 'OR',
            'event_passport' => array(
                'key'  => 'event_product',
                'value' => 'featured',
                'compare' => '=',
            ),
            'event_dates'  => array(
                'key'  => 'event_dates',
                'type' => 'DATETIME',
            )
        ),
        'orderby'    => array(
            'event_passport'  => 'DESC',
            'event_dates' => 'DESC',                    
        ),
);

Say for example I have 3 events where the event_product is featured.

What I want to do is display these 3 featured events first, then show the rest of the events.

At the moment this is not working and I’m not sure what I need to do to achieve this.

Any help is much appreciated, thank you!

2

Answers


  1. You have to get both posts list separately and merge them into one array and use that loop for display post in frontend.

    // Featured posts query
    $args_featured = array(
        'post_type' => 'events',
        'posts_per_page' => 6,
        'meta_query' => array(
            array(
                'key' => 'event_product',
                'compare' => '=',
                'value' => 'featured'
            )
        )
    );
    $featured_query = new WP_Query($args_featured);
    
    $featured_count = $featured_query->post_count;
    
    if ($featured_count < $posts_to_show) {
      
        // non-featured posts query
        $args_notfeatured = array(
            'post_type' => 'my_cpt',
            'posts_per_page' => $posts_to_show - $featured_count,
            'meta_query' => array(
                'meta_query' => array(
                    'relation' => 'OR',
                    array(
                        'key'     => 'event_product',
                        'value'   => 'featured',
                        'compare' => '='
                    ),
                    array(
                        'key'     => 'event_product',
                        'compare' => 'NOT EXISTS'
                    )
                )
            )
        );
        $notfeatured_query = new WP_Query($args_notfeatured);
        
        $full_query = new WP_Query();
        $full_query->posts = array_merge( $featured_query->posts, $notfeatured_query->posts );
        $full_query->post_count = count( $full_query->posts );
        
    } else {
      
        $full_query = $featured_query;
      
    }
    
    
    if ( $full_query->have_posts() ) {
        while ( $full_query->have_posts() ) {
            $full_query->the_post();
            // Output your post HTML
        }
    }
    wp_reset_postdata();
    
    Login or Signup to reply.
  2. try modifying the query directly using posts_clauses filter.

    The code below is untested, but the idea is to join individual table based on its meta key, then modify the order clause based on the value of that meta key.

    add_filter( 'posts_clauses', function ($clauses, WP_Query $q) {
        
        // exit if post type is not event
        if ( $q->get('post_type') != 'events' || is_admin() || !$q->is_main_query() || !is_archive() ) 
            return $clauses;
        
        // left join the meta table for event_product (ep) and event_dates (ed)
        $clauses['join'] = "
        
        LEFT JOIN wp_postmeta as ep ON (wp_posts.ID = ep.post_id)
            AND ep.meta_key = 'event_product'
        
        LEFT JOIN wp_postmeta as ed ON (wp_posts.ID = ed.post_id)
            AND ed.meta_key = 'event_dates'
        
        //order them first if the event_product value is NOT NULL, so the order is NOT NULL = 0 and NULL = 1
        //followed by event_dates descending order
        $clauses['orderby'] = 'CASE WHEN ep.meta_value IS NULL THEN 1 ELSE 0 END, CAST(ed.meta_value AS DATE) DESC";
        
        return $clauses;
    }, 1, 2 );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search