Pageview counts for Movable Type in PHP
I decided it was a bit too ambitious to try to turn my pageview functions into a plugin right now. It will be much easier to just describe it in a post.
First, create a new table called mt_ext_pageview in your Movable Type database. It needs to have three integer fields: entry_id, blog_id, and pageviews. I use PHPMyAdmin for database tasks, and it’s pretty self-explanatory so I won’t go into it here. If you need help leave a comment or email me.
Now create a module template called Pageview Header. This will load all the defaults for accessing the database; you’ll obviously need to edit in your info.
<?php
$host = 'localhost'; // database server hostname
$user = 'matt'; // database username
$password = 'password'; // database password
$database = 'mt3'; // MT database
mysql_connect( $host, $user, $password );
mysql_select_db( $database );
?>
Next create another module template called Pageview Record. This one increments the number of pageviews and then prints it. You’ll link to this one in your individual archive template later. For the IPs you can enter addresses that you (the weblog author) use, then the script won’t count your own hits. If you don’t have three IPs you need to filter just use ‘0.0.0.0′ for the others.
<?php
$remote_ip = "{$_SERVER['REMOTE_ADDR']}";
$my_ip1 = '10.1.1.1';
$my_ip2 = '67.165.220.202';
$my_ip3 = '127.0.0.1';
$pageviews = 0;
$entry_id = $this->tag('MTEntryID');
$blog_id = $this->tag('MTBlogID');
$rs = mysql_query( "SELECT pageviews FROM mt_ext_pageview WHERE entry_id = $entry_id" );
$num = mysql_numrows( $rs );
if ($num > 0) {
$pageviews = mysql_result( $rs, 0 );
} else {
mysql_query( "INSERT INTO mt_ext_pageview (entry_id, blog_id, pageviews) VALUES ($entry_id, $blog_id, 0)" ); }
if1 {
$pageviews++;
mysql_query( "UPDATE mt_ext_pageview SET pageviews = $pageviews WHERE entry_id = $entry_id LIMIT 1;" );
}
if ($pageviews > 0) { echo "| $pageviews pageview"; }
if ($pageviews > 1) { echo "s"; }
?>
Next is Pageview Display. This one will print the number of pageviews an entry has without incrementing the number. It’s what you’ll link to in your indexes where you want to see how popular entries are without adding a pageview.
<?php
$entry_id = $this->tag('MTEntryID');
$rs = mysql_query( "SELECT pageviews FROM mt_ext_pageview WHERE entry_id = $entryID" );
$num = mysql_numrows( $rs );
if ($num > 0) {
$pageviews = mysql_result( $rs, 0 );
if ($pageviews > 0) { echo "| $pageviews pageview"; }
if ($pageviews > 1) { echo "s"; }
}
?>
Now comes the tricky part. At the beginning of the last two snippets of code you’ll see I set the $entry_id and $blog_id variables with these lines.
$entry_id = $this->tag('MTEntryID');
$blog_id = $this->tag('MTBlogID');
Those lines will work in dynamically built templates, but it will have to be changed for static templates to this.
$entry_id = <$MTEntryID$>;
$blog_id = <$MTBlogID$>;
This has something to do with the PHP nature of dynamically generated pages, versus the perl code that static pages are run through. I don’t really want to digress now (I don’t understand it well, anyway) but suffice to say it took me a while to figure it out and I couldn’t have done it without the fine support people at Six Apart. Once MT3.2 comes out of beta I’ll rewrite this whole thing using the new <MTIfDynamic> and <MTIfStatic> tags, but until then it just has to be kludgy. If, like me, you have both dynamic and static index pages just make one version called Pageview Display for the static templates and another called Pageview Dynamic for the dynamic ones.
This code also doesn’t work if you’re caching your dynamic pages. The counter won’t increment after the first hit unless you update the entry, causing it to recache, and then it will just pick up one more hit until the next update. When MT caches a file it preprocesses the PHP code and outputs straight HTML. Then it serves up that HTML to everyone that views the page later, so the PHP code doesn’t get hit again. Even if you set your individual posts to static so the counter increments the displayed counts on your dynamic indexes will be incorrect and jump up in fits and starts. I’m trying to come up with a way around this, but I think it will be complicated and/or in javascript (and I don’t much like javascript). Besides, on a blog the size of mine purely dynamic publishing works just fine.
Now we just have to include the modules in the templates. Put “<MTInclude module=’Pageview Header’>” before the </head> in each of your index templates. Then put “<MTInclude module=’Pageview Record’>” wherever you want the number to print in your individual archive template, and “<MTInclude module=’Pageview Display’>” in all your other templates. Now you’ll be able to see the count from any page and every time someone reads the post all by its lonesome the number will increment.
Popularity: 3% [?]
- $my_ip1 !== $remote_ip) && ($my_ip2 !== $remote_ip) && ($my_ip3 !== $remote_ip [↩]