Custom Post order for homepage

I would like to display a dropdown on the homepage which contains [most popular, most recent, trending] and when a user selects on of them the posts are page reloads and the posts are sorted in that order.

Right now I am using query string to detect the sort order. For eg: http://example.com/?sort=popular or http://example.com/?sort=trending. Then in the home.php I check query string and edit the wp_query object’s orderby clause.

Read More

I want to ask if this is a correct approach or is there a better way to handle this case? Because I also want to handle pagination and other stuff.

In home.php

/**
 * check query for most popular.
 */
function check_for_popular() {
    return get_query_var('sort') == "popular";
}
function mp_home_loop() {
global $wp_query;
    if( check_for_popular() ) {
        $query = $wp_query->query_vars;
        $wp_query = new WP_Query( wp_parse_args( array(
            'meta_key' => 'popularity_score',
            'orderby'  => 'meta_value_num',
            'order'    => 'DESC',
            ), $query ) );
    }
    include( CHILD_DIR . '/mp_home_loop.php' );
} 

In functions.php

add_filter('query_vars', 'add_query_vars' );
function add_query_vars( $qvars ) {
   $qvars[] = 'sort';
   return $qvars;
}

Related posts

1 comment

  1. From a naming standpoint it seems that the term “filter” would be more appropriate since you are filtering by criteria first and then a sort (directional) is applied when you order. But that’s more a naming convention standpoint…

    From a code structure if you are using the check_for_popular() method in several places then it makes sense to structure it as you did. If this is only for the filtering of the function I would go with a switch statement on the args for WP_Query and then execute the query. Something along these lines:

    function mp_home_loop() {
        global $wp_query;
        $filter_args = array();
        switch( get_query_var('sort') ){
            case 'popular':
                $filter_args = array(
                    'meta_key' => 'popularity_score',
                    'orderby'  => 'meta_value_num',
                    'order'    => 'DESC'
                    );
            break;
            case 'trending':
                // obviously assign your own query args
                $filter_args = array(
                    'meta_key' => 'trending_score',
                    'orderby'  => 'meta_value_num',
                    'order'    => 'DESC'
                    );
            break;
        }
        $wp_query = new WP_Query( wp_parse_args( $filter_args, $wp_query->query_vars ) );
        include( CHILD_DIR . '/mp_home_loop.php' );
    } 
    

    Depending on how this query is being used (as in if it is driving your main query) then you might want to migrate this further into a pre_get_posts hook; however, since you mentioned that it was for the homepage I am assuming you have this a particular subsection of the page.

Comments are closed.