Track your WordPress post views.

Posted on April 24, 2011 by Jimmy K. in Tutorials.

I wrote an article previously that outlined the process I personally use to track post views using WordPress. This is an updated version of that article. There were multiple things wrong with my previous method of tracking post views that I have addressed in Version 3.1.1 of my WordPress theme and I am going to share my updated method with you.

The MySQL table wasn’t necessary.

In my previous article, I used a MySQL table to store post views. Pepijn de Vos noted that we didn’t need an extra MySQL table floating around just to store views and he was 100% correct. While we could also use a flat file to store views, this isn’t an ideal solution because multiple things can go wrong: the file could save incorrectly, losing all your accumulated data; the file could be overwritten or accidentally deleted; etc.

What I decided to do was use the wp_postmeta table to store the number of views for each post as if it were meta data supplied by the user. This is useful for three reasons: 1) we don’t need to create a new table to store post views, 2) we can use the built-in get_post_meta(), add_post_meta(), and update_post_meta() functions, and 3) the value can be changed by the user at any time by navigating to the “Custom Fields” section.

We shouldn’t count ourselves.

Since we’re probably the author of our posts, why would we want to skew the data with our constant page refreshes? Well, we don’t! So what I decided to do was add a validation step before incrementing the view count. This step uses the built-in WordPress functions is_user_logged_in() and get_currentuserinfo(). (See, I’m making a conscious effort to use the built-in functions!) This means that only people that meet the following two conditions will be counted as views: 1) Users that are not logged in, or 2) Users that are logged in, but don’t have the same “User ID” as the author.

Where can we display post views?

We can display them anywhere! I choose to display my post views in the sidebar as a “Popular Articles” section; however there are multiple ways this information can be displayed. For example, I show the number of views for each post in the “related posts” section under each article in single.php. (This information can be found beneath the sharing section, but above the comments section in an area labeled “Here are some random, related posts.”)

How to use this code.

While I could have probably created a plugin for this, I’m quite lazy and inexperienced with creating plugins. So! I have the next best thing: A brief walk-through of how to install this code on your own blog!

Paste this code in functions.php. (Or anywhere in your theme, really.)

<?php

/* gets a posts view count. */
function jGetNumPostViews($iPostID) {

	$iNumViews = get_post_meta($iPostID, "NumViews", true);

	if (!$iNumViews) {
		add_post_meta($iPostID, "NumViews", 0, true);
		$iNumViews = 0;
	}

	return $iNumViews;

}

/* updates a posts view count. */
function jRecordPostView($iPostID) {

	$iNumViews = get_post_meta($iPostID, "NumViews", true);

	if (!$iNumViews) {
		add_post_meta($iPostID, "NumViews", 0, true);
		$iNumViews = 0;
	}

	update_post_meta($iPostID, "NumViews", $iNumViews + 1);

}

/* truncate some text. */
function jTruncate($sValue, $iLimit, $sElipses = " [...]") {
	if (strlen($sValue) > $iLimit) $sValue = substr($sValue, 0, $iLimit) . $sElipses;
	return $sValue;
}

?>

The first function, jGetNumPostViews(), is used to retrieve the number of views for a post and the second function, jRecordPostView(), increments the number of views for a post. Both functions attempt to create a new meta record for the post if one doesn’t exist.

Now, paste this code in single.php. It should be placed within The Loop.

<?php

global $current_user; get_currentuserinfo();

if (!is_user_logged_in() || $post->post_author != $current_user->ID) {
	jRecordPostView($post->ID);
}

?>

And finally, paste this code anywhere in your theme to display the most popular articles.

<?php

$sQuery = "SELECT `a`.`id` AS `ID`, `a`.`post_status` AS `Status`, `a`.`post_title` AS `Title`, `b`.`meta_value` AS `NumViews` FROM `wp_posts` AS `a`, `wp_postmeta` AS `b` WHERE `b`.`meta_key` = 'NumViews' AND `b`.`post_id` = `a`.`id` AND `a`.`post_status` = 'publish' AND `post_type` = 'post' GROUP BY `a`.`id` ORDER BY (`b`.`meta_value` + 0) DESC LIMIT 10;";
$oPostViewsQuery = mysql_query($sQuery) or die("Unable to select views! " . mysql_error());

$y = 0; while ($oPostViewsResults = mysql_fetch_assoc($oPostViewsQuery)) {

	echo "<div class=\"full " . ($y++ == 0 ? "top" : "") . "\">";
	echo "<span>&raquo;</span><a href=\"" . get_permalink($oPostViewsResults['ID']) . "\">" . jTruncate($oPostViewsResults['Title'], 35) . "</a><span class=\"help\">(" . number_format($oPostViewsResults['NumViews']) . ")</span>";
	echo "</div>\n";

}

?>

So there you have it! If you have any questions or suggested improvements for this article, please feel free to share them in the comments. Thanks for stopping by!

- EDIT -

I forgot to include the jTruncate() function. The code has been updated.

- EDIT -

Due to the data format of the `wp_postmeta` table, the MySQL query used to retrieve popular articles was improperly sorting the results, displaying post-sorting values like “94, 58, 40, 42, 105″. The query has been updated to be “ORDER BY (`b`.`meta_value` + 0)”, which will convert the string data to a number for proper sorting.

Tags: ,

 

Jimmy K. is a Chicago-based web developer who actively posts tutorials, articles and insights on his web development blog to help other programmers and developers.

You can find Jimmy on Google+ and Twitter.

 
 
 
 
 

If you like this, please leave a comment.

Name (required)
Email Address (required)
Website
Comments: