Modify a query using both a text field and a true/false AFC field

I have found the solution to my question and I share it. I hope someone else will find it useful in the future.

I am not a developer and surely the code can be improved, but this one worked for me for what I wanted.

I needed to show a list of posts ordered by the following parameters:

First, show the posts grouped by a custom field: custom_field_to_group_posts. With this, we group all the posts with the same value in that custom field.

Second, within each grouping of posts, the posts should be displayed in alphabetical order.

Finally, if any post is marked as featured using an ACF custom field true/false, that post should be moved to the top of the list within the grouped posts.

To be understood, I want to group the posts by city and within each city the featured post will be the first of that city.

  • post_A cityA

  • post_B cityA

  • post_C cityA

  • post_D cityB FEATURED

  • post_A cityB

  • post_B cityB

  • post_C cityB

  • post_C cityC FEATURED

  • post_A cityC

  • post_B cityC

This is the code I used and it worked for me.


add_action( 'pre_get_posts', 'my_custom_query' );

function my_custom_query( $query ) {
    
     // Do not add meta arguments in admin pages
    if (is_admin()) {
        return;
    }

    if( $query->is_main_query() && is_post_type_archive( 'my_CPT_name' ) {
        
        //Get original meta query
        $meta_query = (array)$query->get('meta_query');

        // Add your criteria
        $query->set( 'posts_per_page', '8' );
        
        $meta_query = array(
            
            'custom_field_to_group_posts' => array(
                'key' => 'custom_field_to_group_posts', // The name of my custom field
            ),
            
            'featured_my_cpt' => array(
                'key' => 'featured_my_cpt', // The name of the true/false ACF field
            ),
        );

        // Set the meta query to the complete, altered query
        $query->set( 'meta_query', $meta_query );
        $query->set( 'orderby', array( 'custom_field_to_group_posts' => 'ASC', 'featured_my_cpt' => 'DESC', 'title' => 'ASC'  ) );
        
    }
}