Popular posts for “Count per Day” WordPress plugin

popularpostsLeaseWeb Labs runs on WordPress and we are using the “Count per Day” plugin to keep track of our visitors. One big advantage of Count per Day is that it does not use cookies, but counts the amount of unique IP addresses per day. These are reported as “visitors”, while the amount of page views are reported as “reads”. In our experience this is a very simple and reliable way of measuring the visitors on our site. Especially when you enable the option “Cache: Count visits with ajax” in the Settings, because that will prevent bots from showing up in the statistics.

Some posts are better and thus more popular than other posts. When people visit your site for a certain post, they may also be interested in other popular posts. This is why we wanted the most popular posts listed in the sidebar (as you can see on the left). Since the popularity of posts is changing all the time and we did not feel like maintaining a static list of posts in menu. Count per Day has a the shortcode “CPD_MOST_VISITED_POSTS” to generate this list for you. Unfortunately this code generates the list including numbers and a heading. This is not exactly the way we like it and thus we created a WordPress widget for our (and your) convenience.

The widget can be simply dragged into a widget area and allows you to:

  • Set the title for the list
  • Set the amount of days to take into account
  • Set the maximum number of items in the list
  • Show/hide the counts for the selected period
  • Show/hide the header that explains the counts

We contacted Tom Braider (the author of this fantastic plugin) and we hope he will include the widget in a next version. Until then you can install the widget by adding the following code to “widgets.php” using the theme editor:

if (isset($count_per_day)) {

// Creating the widget
class PopularPostsWidget extends WP_Widget {

  function __construct() {
    parent::__construct(
      // Base ID of your widget
      'cpd_popular_posts_widget',
      // Widget name will appear in UI
      'Popular Posts',
      // Widget description
      array( 'description' => 'Count-Per-Day Popular Posts'));
  }

  // Creating widget front-end
  // This is where the action happens
  public function widget( $args, $instance ) {
    $title = apply_filters( 'widget_title', $instance['title'] );
    $days  = $instance['days' ]+0;
    $limit = $instance['limit']+0;
    $head  = $instance['head' ]?true:false;
    $count = $instance['count']?true:false;
    // before and after widget arguments are defined by themes
    echo $args['before_widget'];
    if ( ! empty( $title ) ) {
      echo $args['before_title'] . $title . $args['after_title'];
    }
    // This is where you run the code and display the output
    global $count_per_day;
    $html = $count_per_day->getMostVisitedPosts($days, $limit, 1, 1, 1);
    if (!$head ) $html = preg_replace('/<small>[^<]*<\/small>/','',$html);
    if (!$count) $html = preg_replace('/<b>[^<]*<\/b>/','',$html);
    echo $html;
    echo $args['after_widget'];
  }

  // Widget Backend
  public function form( $instance ) {
    $title = isset($instance['title'])?$instance['title']:'Popular Posts';
    $days  = isset($instance['days' ])?$instance['days' ]:'7';
    $limit = isset($instance['limit'])?$instance['limit']:'10';
    $head  = isset($instance['head' ])?$instance['head' ]:false;
    $count = isset($instance['count'])?$instance['count']:false;
    // Widget admin form
    ?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'days' ); ?>"><?php _e( 'Days:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'days' ); ?>" name="<?php echo $this->get_field_name( 'days' ); ?>" type="text" value="<?php echo esc_attr( $days ); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'limit' ); ?>"><?php _e( 'Limit:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'limit' ); ?>" name="<?php echo $this->get_field_name( 'limit' ); ?>" type="text" value="<?php echo esc_attr( $limit ); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'head' ); ?>"><?php _e( 'Show header:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'head' ); ?>" name="<?php echo $this->get_field_name( 'head' ); ?>" type="checkbox" <?php echo $head?'checked="checked"':'' ?> />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'count' ); ?>"><?php _e( 'Show counters:' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'count' ); ?>" name="<?php echo $this->get_field_name( 'count' ); ?>" type="checkbox" <?php echo $count?'checked="checked"':'' ?> />
</p>
    <?php
  }

  // Updating widget replacing old instances with new
  public function update( $new_instance, $old_instance ) {
    $instance = array();
    $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
    $instance['days' ] = ( ! empty( $new_instance['days' ] ) ) ? strip_tags( $new_instance['days' ] ) : '';
    $instance['limit'] = ( ! empty( $new_instance['limit'] ) ) ? strip_tags( $new_instance['limit'] ) : '';
    $instance['head' ] = ( ! empty( $new_instance['head' ] ) ) ? strip_tags( $new_instance['head' ] ) : '';
    $instance['count'] = ( ! empty( $new_instance['count'] ) ) ? strip_tags( $new_instance['count'] ) : '';
    return $instance;
  }
} // Class PopularPostsWidget ends here

// Register and load the widget
add_action( 'widgets_init', function (){ register_widget('PopularPostsWidget'); });

}
Share

5 thoughts on “Popular posts for “Count per Day” WordPress plugin”

  1. Nice post but what happens to all of those users that access trough NAT or Proxy?
    Nowadays most of the wireless ISPs (vodafone, orange, etc) do NAT/Proxy their entire 3G/4G networks to save public ip addresses you may have thousands of hits that will appear to access just from 1 IP address.
    This will also happen to most of the corporations that also just have a handful of exit gateways.
    These kind ways of accessing the Internet will skew the results.
    Cheers,
    Pedro

  2. @Pedro: You are absolutely right, but we are guaranteed to have at least the amount of unique visitors reported. Also the reads show the amount of total hits. So the actual visitor count maybe somewhere between those two values. Now you know that when we talk about our visitors we are not exaggerating 😉

  3. Thanks for this!

    I’ve been going back and forth with choosing analytics that would give me a simple way to also get popular posts. This solution seems to be exactly what I need without unnecessary bloat 🙂

    When i get the time this week I’ll try and implement thumbnails into the display as well.

    PS. (to help spread good developement) in case you’re interested, I’m anxiously awaiting for this comment system to be released by the end of this month (as the author claims) so here’s the link for his github https://github.com/jacobwb

    This should be awesome for serving comments on static cached pages

  4. Hi,

    I am using Count per day for several years and I love it. This widget is a big advantage but I have one small problem:
    The theme I use is Sahifa (Tielabs) and my landingpage is a real (home) page with slider and bloglist, not the normal used bloglist.
    This widget show how many people visited this homepage but I don’t want to show this to the visitors. Can I hide this peticular page from the widget?

    Regards,

    Siegfried Geryl

  5. @Siegfried: Insert a line between line 31 and 32 with the search and replace on the “$html” variable, something like this:

    $html = preg_replace('/insert regex that matches the entry you want removed here/','',$html);

    But you will have to adjust the PHP code (and regex) to reflect your entry. Does that help?

Leave a Reply

Your email address will not be published. Required fields are marked *