I downloaded a widget that would display the most popular/most visited pages, but unfortunately the widget didn't come with an 'Exclude Posts' field, which would be really useful to me.

So for the last few days I've been trying to figure out a way to make it do that, whether on the user end or the wordpress code end, all to no avail.

My closest thought is within the tracking code which collects data on each page using query, I should be able to exclude which posts the plugin tracks with the query. That code is here:

    private function update_stats() {
    global $wpdb;

    if ( $this->post_id ) {
        // Get the existing raw stats
        $raw_stats = $wpdb->get_var( $wpdb->prepare( "SELECT raw_stats FROM {$wpdb->prefix}most_popular WHERE post_id = '%d'", array( $this->post_id ) ) );
        $date = gmdate('Y-m-d');

        if ( $raw_stats ) {
            $raw_stats = unserialize( $raw_stats );
        } else {
            // Create a entry for this post
            $wpdb->query( $wpdb->prepare( "INSERT INTO {$wpdb->prefix}most_popular (post_id, last_updated, 1_day_stats, 7_day_stats, 30_day_stats, all_time_stats, raw_stats) VALUES ('%d', NOW(), '0', '0', '0', '0', '')", array('tag__not_in', 'array(4)', $this->post_id ) ) );

        $count_1 = $this->calculate_1_day_stats( $raw_stats, $date );
        $count_7 = $this->calculate_7_day_stats( $raw_stats, $date );
        $count_30 = $this->calculate_30_day_stats( $raw_stats, $date );

        if ( isset( $row_stats ) && count( $raw_stats ) >= 30 ) {
            array_shift( $raw_stats );
            $raw_stats[$date] = 1;
        } else {
            if ( ! isset( $raw_stats[$date] ) ) {
                $raw_stats[$date] = 1;
            } else {

        // Update our table with new figures
        $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}most_popular SET 1_day_stats = '{$count_1}', 7_day_stats = '{$count_7}', 30_day_stats = '{$count_30}', all_time_stats = all_time_stats + 1, raw_stats = '%s' WHERE post_id = '%d'", array('tag__not_in', 'array(4)', serialize( $raw_stats ), $this->post_id ) ) );

As you can see, I've added the array(tag__not_in', 'array(4)'. This was one of my attempts.

Right now the way I'm hiding the pages I don't want showing is by giving them a specific tag and saying "display:none" in my css. While this works, it is far from ideal, as they can still be seen in the source code. In this case, that tag's id is 4.

If I could make it work the same way, just without the css, that would be perfect.

  • You want to exclude posts from displaying in the most popular posts list? Then the display part might be of relevance.
    – birgire
    Nov 19, 2016 at 16:42
  • What I want to do is exclude certain posts/pages with a certain tag. The reason I have them set to display:none is because it is picking the top 10 most visited pages to show, however some of those are pages like the homepage, or things like that. So to counteract this, I'm having to tell it to show the top 14 pages and using css to target the items that I want to hide and hide them using display:none. The problem with doing this, however, is that these pages still exist in the source code. I want the plugin to completely ignore the page id's or tag id's that I select. Nov 19, 2016 at 16:59
  • By "display part" I meant the code in the display class method. Maybe you can fetch data from the 'page' or 'post' post types only?
    – birgire
    Nov 19, 2016 at 17:04
  • Your main problem is understanding the $wpdb->query() and $wpdb->prepare() methods. While the first runs a raw query, the later prepares a query string pretty much the same way PHP does with printf() and sprintf(). By now you should receive errors for providing the wrong count of arguments. Every %s (string) and every %d (digit/number) should have its replacement in the order of appearance. Make sure to read how those functions work. And make sure to test your strings with for e.g. PhpMyAdmin or on the command line of the mysql server. And tag__not_in is a WP_Query arg.
    – kaiser
    Nov 20, 2016 at 15:04


Your Answer

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

Browse other questions tagged or ask your own question.