2

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.

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;
}
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.

  • Just to add a few things, I have a to show on the homepage posts will be sorted by [Most Recent, Most Viewed, Trending]. So I have to modify the main home loop. – Ahmed Mar 21 '14 at 4:41
  • I wasn't sure of all the sorting options you needed for implementation, just wanted to offer the construct process I would use for generating the filters for the use of WP_Query – codearachnid Mar 21 '14 at 10:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.