简体   繁体   中英

ACF/Wordpress: Sort post list by multiple values in frontend

I have the following code which is working fine and sorting the post based on the custom field assigned to each post using ACF plugin. Here is the code used for that purpose

function my_pre_get_posts( $query ) {


// only modify queries for 'event' post type
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post' ) {
    
    $query->set('order', 'ASC'); 
    $query->set('orderby', 'meta_value');    
    $query->set('meta_key', 'active_inactive');    
    
}

// return
return $query;

}

add_action('pre_get_posts', 'my_pre_get_posts');

I have a custom field created using ACF which is called active_inactive and it has 2 values to each post, active and inactive.

The first requirement works fine, where all active posts are showing first in the list and then inactive posts, however, dates are not being sorted correctly, and right after active posts, all the inactive posts are sorted from older date first to the end date at last.

So i need to fix dates as well, so right after the active posts list ends and inactive posts lit start, all those inactive posts should be start from the latest date to the oldest date.

Any help would be appreciated.

Trying something like that but it is not returning any results due to post_date

function my_pre_get_posts( $query ) {

if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post' ) {
    
    $meta_query = array(
        'active_inactive' => array(
            'key' => 'active_inactive',
            'compare' => 'EXISTS'
        ),
        'post_date' => array(
            'key' => 'post_date',
            'compare' => 'EXISTS'
        ),
    );
    $order_by = array(
        'active_inactive' => 'ASC',
        'post_date' => 'DESC'
    );
    
    $query->set( 'meta_query', $meta_query );
    $query->set( 'orderby', $order_by );
    $query->set( 'posts_per_page', -1 );
 }
}
add_action( 'pre_get_posts', 'my_pre_get_posts' );

You can add another meta_key parameter to sort the inactive posts by date in descending order after the active posts by using the meta_query parameter.

You can use the meta_query parameter to specify multiple sorting criteria, and set the meta_query parameter as an array of arrays, each array containing the meta_key, meta_value, and order parameters.

function my_pre_get_posts( $query ) {
if( isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post' ) {
    $query->set('order', 'ASC'); 
    $query->set('orderby', 'meta_value');    
    $query->set('meta_key', 'active_inactive');
    $query->set('meta_query', array(
        'relation' => 'OR',
        array(
            'key'     => 'active_inactive',
            'value'   => 'active',
            'compare' => '='
        ),
        array(
            'key'     => 'date',
            'compare' => 'EXISTS',
        ),
        array(
            'key'     => 'date',
            'value'   => date("Ymd"),
            'compare' => '<=',
            'type'    => 'DATE'
        ),
        array(
            'key'     => 'active_inactive',
            'value'   => 'inactive',
            'compare' => '='
        ),
        array(
            'key'     => 'date',
            'compare' => 'EXISTS',
        ),
        array(
            'key'     => 'date',
            'value'   => date("Ymd"),
            'compare' => '<=',
            'type'    => 'DATE'
        ),
        array(
            'key'     => 'date',
            'order'   => 'DESC',
            'compare' => 'EXISTS',
            'type'    => 'DATE'
        )
    ));
}
return $query;
}
add_action('pre_get_posts', 'my_pre_get_posts');

I've added three more arrays to the meta_query parameter: The first array checks if the date field exists and is less than or equal to today's date, this will exclude the future events. The second array checks if the post has active_inactive value equals to inactive. The third array sorts the inactive posts by date in descending order. Also, I've added a relation parameter set to OR so that both conditions will be met.


    function my_pre_get_posts($query)
    {
        if (isset($query->query_vars['post_type']) && $query->query_vars['post_type'] == 'post')
        {
            $meta_query = array(
                'active_inactive' => array(
                    'key' => 'active_inactive',
                    'compare' => 'EXISTS'
                ),
                'modified' => array(
                    'key' => 'modified',
                    'type' => 'date',
                    'compare' => 'EXISTS'
                ),
            );
            $order_by = array(
                'active_inactive' => 'ASC',
                'modified' => 'DESC'
            );
            $query->set('meta_query', $meta_query);
            $query->set('orderby', $order_by);
        }
        else
        {
            $meta_query = array(
                'active_inactive' => array(
                    'key' => 'active_inactive',
                    'compare' => 'EXISTS'
                ),
                'modified' => array(
                    'key' => 'modified',
                    'type' => 'date',
                    'compare' => 'EXISTS'
                ),
            );
            $order_by = array(
                'active_inactive' => 'ASC',
                'modified' => 'DESC'
            );
            $query->set('meta_query', $meta_query);
            $query->set('orderby', $order_by);
        }
    }

    add_action('pre_get_posts', 'my_pre_get_posts');

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM