Sort query loop by post view count for logged out users
The following code does the following:
- Creates a custom field named
post_views_count
. - When a logged out visits a posts, the visit counter is incremented by
1
. - Query loop displays most visited posts in a descending order.
- Any posts with no visits get added to the query after the visited posts in a published date descending order.
//Record the number of post views add_action('generate_after_do_template_part', function(){ setPostViews(get_the_ID()); } ); function setPostViews($postID) { if (!is_single()) { return; // Abort if not a single post } // Check if user is logged in $user_id = get_current_user_id(); if ($user_id != 0) { return; // Abort if user is logged in } $count_key = 'post_views_count'; $count = get_post_meta($postID, $count_key, true); // If count is blank or not set, initialize it to 1 if ($count === '') { $count = 1; update_post_meta($postID, $count_key, $count); } else { $count++; // Increment the count update_post_meta($postID, $count_key, $count); } } // Sort trending posts function gb_query_by_views( $query_args, $attributes ) { if ( ! empty( $attributes['className'] ) && strpos( $attributes['className'], 'trending-articles' ) !== false ) { $custom_args = array( 'orderby' => array( 'meta_value_num' => 'DESC', // Sort by views 'date' => 'DESC' // Then sort by date ), 'order' => 'DESC', 'ignore_sticky_posts' => 1, // Treat sticky posts as regular posts 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'post_views_count', 'compare' => 'NOT EXISTS' ), array( 'key' => 'post_views_count', 'compare' => 'EXISTS' ) ) ); } else { return $query_args; } // Merge the custom args into the original query args $merged_args = array_merge( $query_args, $custom_args ); return $merged_args; } add_filter( 'generateblocks_query_loop_args', 'gb_query_by_views', 10, 2 );
Just insert the code to your child theme’s functions.php file. Insert your query loop and add the class of trending-articles
to the query loop grid block.