I want to make a filter list for my posts (in homepage, search page and archive page) Here is an example of what i'm looking for

Sort by: - Date (/?orderby=date) - Random (/?orderby=rand) - Views (here i need an orderby=views or something like that)

I'm counting and viewing post views by using this code:

// Count views
function setPostViews($postID) {
  $count_key = 'post_views_count';
  $count = get_post_meta($postID, $count_key, true);
  if($count=='') {
    $count = 0;
    delete_post_meta($postID, $count_key);
    add_post_meta($postID, $count_key, '0');
  } else {
    update_post_meta($postID, $count_key, $count);

// Show views
function getPostViews($postID) {
  $count_key = 'post_views_count';
  $count = get_post_meta($postID, $count_key, true);
  if($count=='') {
    delete_post_meta($postID, $count_key);
    add_post_meta($postID, $count_key, '0');
    return "0 View";
  return $count.' Views';

// Show views in WP-Admin
add_filter('manage_posts_columns', 'posts_column_views');
add_action('manage_posts_custom_column', 'posts_custom_column_views', 5, 2);
function posts_column_views($defaults) {
  $defaults['post_views'] = __('Views');
  return $defaults;
function posts_custom_column_views($column_name, $id){
  if($column_name === 'post_views') {
    echo getPostViews(get_the_ID());

Is this possible?


1 Answer 1


You can sort your query by view number, using the meta key :

$query = new WP_Query( 
                'meta_key' => 'post_views_count',
                'orderby' => 'meta_value_num',
                'order' => 'DESC',

This will query your posts based on the views. You can change DESC to ASC or RAND to achieve what you asked.

To make it work in action, you can use pre_get_posts() to filter your query. Use this piece code in your theme's functions.php file:

add_action( 'pre_get_posts', 'my_view_filter' );
function my_view_filter($query){
    if ( 
        !is_admin() && 
        $query->is_main_query() && 
        ( $query->is_home() || $query->is_archive() || $query->is_search() )
    ) {
        if (isset($_REQUEST['orderby'])) {
            $order = $_REQUEST['orderby'];
        if ( $order === 'views') {
            $query->set('meta_key', 'post_views_count');
            $query->set('orderby', 'meta_value_num');
            $query->set('order', 'DESC');

Now, whenever you visit http://example.com/?orderby=views, your posts will be filtered by the number of views ( descending, you can change it to anything you want )

  • Where I have to put this to make a filter list with 3 options like: option 1 - Date / option 2 - Random / option 3 - Views Commented Jun 5, 2017 at 1:02
  • @HankScorpio Hi, You didn't mention where are you going to use this so i posted the general solution for it. Please add more details to your question (including where and how do you want to use this filter, maybe even an example) and possibly add your current code, so i can write an accurate answer.
    – Johansson
    Commented Jun 5, 2017 at 1:04
  • Yes, sorry... question edited check it now Commented Jun 5, 2017 at 1:28
  • buddy, i received a fatal error when i use your code... "Fatal error: Call to a member function is_main_query() on null" what it's wrong? Commented Jun 5, 2017 at 2:26
  • @HankScorpio Oops sorry, i forgot to add $query to the functions arguments. It should be my_view_filter($query) instead of my_view_filter().
    – Johansson
    Commented Jun 5, 2017 at 2:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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