Ordering Posts by Number of Views
This was a particularly vexing one. After installing Lester Chan’s WP-PostViews plugin (http://lesterchan.net/portfolio/programming/php/) I thought I would be able to easily set up a “Most Viewed” block ordered by number of views. The WP Codex says that you can use meta_key and meta_value in query_posts. Since views is a new meta_key added by the plugin, theoretically you should be able to do something like this:
query_posts("meta_key=views&orderby=meta_value&order=DESC");
That would show your posts from most to least viewed.
If only it were so easy. If you test it out, you’ll see the display order seems to be completely random. Fortunately, a ton of searching led me to this post: http://gabrieljones.com/order-posts-by-meta-value-numbers-in-wordpress/ – where Gabriel Jones figured out that the issue is with the field type in the WP dbase. meta_value is a longtext field type and that doesn’t allow for numeric comparisons.
His solution involves a couple of edits to the query.php file, which is found in your wp-includes folder.
First, search for
// Used to filter values
$allowed_keys = array('author', 'date', 'title', 'modified', 'menu_order', 'parent', 'ID', 'rand', 'comment_count');
if ( !empty($q['meta_key']) ) {
$allowed_keys[] = $q['meta_key'];
$allowed_keys[] = 'meta_value';
It was approx. line 2000 in my file. Then, immediately after the above, paste in the following:
$allowed_keys[] = 'meta_value_number';
Next, scroll down a few lines to:
// Only allow certain values for safety
$orderby = $orderby_array[$i];
switch ($orderby) {
case 'menu_order':
break;
and immediately after that paste in
case 'meta_value_number':
$orderby = "$wpdb->postmeta.meta_value+0";
break;
This allows another option in query_posts, meta_key_number, and it forces it to convert to an integer by taking the returned value and adding zero. Now you’re working with numbers and you can sort whichever way you like. The revised query_posts to accomplish ordering by number of views is:
query_posts("meta_key=views&orderby=meta_value_number&order=DESC");
Works brilliantly. Much thanks to him for this solution. If you use this yourself, make sure to keep a backup of query.php (I just make a duplicate of the revised file called query-original.php) and store it somewhere so that if a later update of WordPress changes things, you won’t lose your work. And hopefully this bug will be corrected in an upcoming release and you won’t even need the workaround.

June 7th, 2010 at 4:14 pm
Brilliant! I’ve found similar posts on this method, but all of them contained typos and didn’t quite explain how to use it. Thank you so much for your post! I really appreciate it.