Archive sorting functions by custom fields (front-end)

I want to give the users the ability to sort the posts in the archive by some custom fields that I pre-define.

The end result would be en a tabbed container, and the user will click on the relevant filter-link that he/her want to see.

As an example: http://www.metacritic.com/browse/games/genre/date/action/all

I want to:
– Filter by date
– Filter by title
– Filter by meta_key

Is this possible to do?

Thanks for all help.. 🙂

2 Answers
2

NOTES: Regarding Jan Fabry’s answer…
Be sure to sanitize that incoming data first, else you’re opening yourself to all sorts of nasty query strings..

You should also probably return the incoming data on that filter, return $query, in place of return;

I also think it would be preferable to have an array of possible values or do a query for possible meta values, that way you can build a switch that can check the incoming value matches against one of those possible values (easier way to sanitize the data coming in).

Not a regular user here, else i’d post an example (no idea how posting code works here – couldn’t find it in the FAQ).

EDIT: Thanks for the poster pointing me to info for posting code.

Example follows, hopefully it works out ok… 🙂

// Only add the needed meta orders
$possible_orders = array( 'some_meta_key', 'some_other_meta_key' );

add_filter( 'pre_get_posts', 'archive_meta_sorting' );
function archive_meta_sorting( $query_object ) {
    if( !is_archive() || is_admin() )
        return $query_object;

    if( !isset( $_GET['orderby'] ) )
        return $query_object;

    global $possible_orders;

    $orderby = trim( $_GET['orderby'] );    

    switch( $orderby ) {
        case( in_array( $orderby, $possible_orders ) ):
            $query_object->set( 'orderby', 'meta_value' );
            $query_object->set( 'meta_key', $orderby );
            break;
        // You don't actually need these two cases below, it will work without them
        // The switch could actually just be a simple if in_array condition..
        case 'title':
            $query_object->set( 'orderby', 'title' );
            break;
        case 'date':
            $query_object->set( 'orderby', 'date' );
            break;
    }
    return $query_object;
}

You only need to pass in values for the meta sorting, the title and date will work just fine using the native support for ordering by those values, same can be said for order(desc or asc).

I hope that helps…

Leave a Comment