I'm looking to display a weekly list of 'Popular Posts' on a site. Currently the list shows a 'Popular Posts' column but these are posts from no particular timeframe. It's displaying the most popular posts from the beginning of the website.

Here's my code...

// Track post view count for popular posts
function track_post_view( $post_id ) {
$count_key  = 'post_views_count';
$count      = get_post_meta( $post_id, $count_key, true );

if( ! $count ) {
    $count = 0;

return update_post_meta( $post_id, $count_key, ++$count );

// Get popular posts
function get_popular_posts( $limit = 3 ) {
// WP_Query arguments
$args = array (
    'post_type'             => 'post',
    'post_status'           => 'publish',
    'posts_per_page'        => $limit,
    'order'                 => 'DESC',
    'orderby'               => 'meta_value',
    'meta_key'              => 'post_views_count',
    'meta_type'             => 'NUMERIC',

// The Query
$popular = new WP_Query( $args );

// Restore original Post Data

return $popular;

So, is this doable? If so, anyone able to suggest a method? I've had a look through various similar questions, but haven't found a concrete answer.

Thanks in advance.

  • By "weekly" do you mean posted in the past week or viewed in the past week? Jul 6, 2015 at 3:12
  • @user1672694 Viewed in the last week. Jul 6, 2015 at 7:49

1 Answer 1


The best way to do this would be to set up a custom table. For each view you would add a new row which would contain (at least) a uid, the post id and the date/time. The beauty of this method is you can store as much data per view as you like, such as IP or the current user if they're logged in. I can't really give any more advise than that as I've never attempted to use custom tables however there are plenty of plugins out there that can do it. The codex article can be found here.

Another way to do it would be using post meta similar to how you've been doing it. What you do is store an array of view times. This way, you wouldn't have to store the view count although I'm sure you'd want to keep the old data for the purpose of records. However this would end up with a really bloated function trying to sort your posts.

I've done up some code below that should work in theory but I haven't had a chance to test it.

//Track page view
function track_post_view( $post_id ) {
    $views_key  = 'post_views_times';
    $views = get_post_meta( $post_id, $views_key, true );
    $count = count( $views );

    if( $count === 0 ) {
        $views = array();

    //Adds another entry to the views with the current UNIX timestamp
    $views[] = time();

    return update_post_meta( $post_id, $views_key, $views );

//Get all posts

function get_popular_posts( $limit = 3 ) {

    $all_posts = new WP_Query( 'post_type' => 'post', 'post_status' => 'publish' );

    //Store these posts
        $post_views = get_post_meta( get_the_ID(), 'post_views_times' );
        $week_ago_time = time() - 7 * 24 * 60 * 60; //This is the timestamp of 1 week ago
        for( $i = 0; $i < count( $post_views ); $i++ ){
            if( $post_views[$i] < $week_ago_time ){ 
                unset($post_views[$i]); //If the timestamp is less than 1 week ago get remove it from the variable
        $posts_list[] = array( 'views' => count( $post_views ), 'post_id' => get_the_ID() );

    //Get the column to sort the $posts_list by
    foreach ($posts_list as $key => $row) {
        $views[$key]  = $row['volume'];

    array_multisort( $views, SORT_DESC, $posts_list ); //This sorts descending by views.

    //Get the top 3 viewed posts and store that it yet another array
    for( $i = 0; $i < $limit; $i++ ){
        $most_viewed_ids[] = $posts_list[$i]['post_id'];

    $popular = new WP_Query( 'p' => $most_viewed_ids ); //Run a query getting our 3 top posts


    return $popular;


I hope this answer helps in some way or another

  • Thanks. Unfortunately that didn't work. It causes an error and the functions.php file needs to be reset to previous version. Jul 18, 2015 at 0:15
  • @KelvinFarrell what is the error? Jul 18, 2015 at 3:50
  • I'm not sure. After I save the changes, it just fails to load any page on the website and shows only a blank white screen. Aug 6, 2015 at 11:50
  • @KelvinFarrell ok that means that's it's giving a fatal error but your debug is turned off, so the error message is hidden. Here's how you can turn on WP_DEBUG: premium.wpmudev.org/blog/… Aug 6, 2015 at 12:49

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.