In loop: posts have thumbnail AND other variables

You can make use of the custom field parameters in WP_Query like you have, you just need to extend it a bit further

You can do your sorting by post_views_count and use meta_query to get all posts that has the highest post view count and has a post thumbnail

You can probably try something like this

$args = array(
    'order'             => 'DESC',
    'posts_per_page'    => 20,
    'meta_key'          => 'post_views_count',
    'orderby'           => 'meta_value_num',
    'meta_query'        => array(
        'relation'      => 'AND',
        array(
            'key' => 'post_views_count',
            'compare' => 'EXISTS'
        ),
        array(
            'key' => '_thumbnail_id',
            'compare' => 'EXISTS'
        ),
    ),
);
$popularPosts = new WP_Query( $args );

For a more accurate post view count, check out this post I have done on the subject. It is very accurate and does not count double views

EDIT

Just on a side note, you need to reset your custom query, and for that matter, any and all custom queries as they will be influenced and will influence other queries. Just after <?php endwhile; ?>, add <?php wp_reset_postdata(); ?>

EDIT 2

I have tested your code, and it does break my sidebar content. I have modified your code to the code below. It does work as expected, only posts from the last thirty are retrieved according to the fact that it has post thumbnails and ordered by highest post count. I am also testing this on localhost. One other thing that you need to take note of, you have to have WordPress 3.9+ for this to work

You don’t have to specify a value when using the ‘EXISTS’ or ‘NOT EXISTS’ comparisons in WordPress 3.9 and up.

<?php if (is_home()) : ?>
    <section class="featured-posts clear">
        <?php
        function filter_where($where="") {
        //posts in the last 30 days
            $where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
            return $where;
        }

        add_filter('posts_where', 'filter_where');

        $args = array(
            'order'             => 'DESC',
            'posts_per_page'    => 20,
            'meta_key'          => 'post_views_count',
            'orderby'           => 'meta_value_num',
            'meta_query'        => array(
                'relation'      => 'AND',
                array(
                    'key' => 'post_views_count',
                    'compare' => 'EXISTS'
                ),
                array(
                    'key' => '_thumbnail_id',
                    'compare' => 'EXISTS'
                ),
            ),
        );
        $popularPosts = new WP_Query( $args );

        remove_filter('posts_where', 'filter_where');

        $counter = 1; ?>

        <?php while ($popularPosts->have_posts() ) : $popularPosts->the_post(); ?>
        <article class="box-<?php echo $counter++; ?>">
            <a href="https://wordpress.stackexchange.com/questions/162908/<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail(); ?>
                <span><?php the_title(); ?></span>
            </a>
        </article>
        <?php endwhile; ?>
        <?php wp_reset_postdata(); ?>

    </section>
<?php endif; // is_home ?>

EDIT 3

You can also use the approach described in this answer by @ialocin to one of my questions to apply and remove a filter using pre_get_posts. This code can be very easily adapted to be used on your custom query. I personally think that this is a better method to use to apply and to remove your custom filter for your custom query

Leave a Comment