Tim Herbert
Tim Herbert

Reputation: 120

Wordpress sort by meta values

I have an issue I am trying to solve right now and having an issue finding a way to do it properly.

I have a college lecture series I need to sort I can sort it by a meta field for year just fine. But when I get to sorting by semester it sorts it in alphabetical and so it ends up sorting by Winter,Spring,Fall or Fall,Spring,Winter depending on if I tell it ASC or DESC.

I need to figure out how to do order this in the right order preferably without adding another field to the posts for sort priority

Query args currently written as follows which is obviously a bit messy.

$args = array(
              'post_type' => 'mcm_geri-ed',
              'posts_per_page' => $posts_per_page,

              'meta_query' => array(
                  'semester' => array(
                      'key' => 'semester',

                  ),
                  'year' => array(
                      'key' => 'year'
                  )
              ),
              'orderby' => array(

                  'year' => 'DESC',
                  'semester' => array(
                    'value' => 'date'
                  )
              ),
              'paged' => $paged
            );

Upvotes: 0

Views: 235

Answers (2)

Tim Herbert
Tim Herbert

Reputation: 120

This is what I ultimately did. It was something different than what was suggested but using the filter suggested to get the result. The if statement has a couple of other caveats added to it due to the way I've built a sorting system for the page template. I also wrote this in a test environment hence the different post type from the original code.

// Custom Orderby filter to return the correct order for semester values. 
add_filter('posts_orderby', 'orderby_pages_callback', 10, 2);
function orderby_pages_callback($orderby_statement, $wp_query) {
    //Making sure this only happens when it needs to. Which is the right post type and if it isn't getting sorted by other functions. 
    if ($wp_query->get("post_type") === "test_semester" && !is_admin() && !isset($_GET['order']) && !isset($_GET['sort']))  {
        return "CAST(mt1.meta_value AS CHAR) DESC, wp_postmeta.meta_value = 'Fall' DESC, wp_postmeta.meta_value = 'Winter' DESC, wp_postmeta.meta_value = 'Spring' DESC,wp_postmeta.meta_value = 'Summer' DESC";

    } else {
        //return your regularly scheduled programming
        return $orderby_statement;
    }
}

Upvotes: 0

janh
janh

Reputation: 2972

I don't think there is a way to do this with WP_Query directly. How about using posts_orderby and manipulating the ORDER-part of the SQL to be something like meta_year DESC, meta_semester = 'Spring' DESC, meta_semester = 'Fall' DESC. Look at the generated SQL to see what names you should use for meta_year and meta_semester (or trimester, really).

This isn't as effective as changing semester to a numerical value and adding the name while outputting, but it will work.

Upvotes: 1

Related Questions