Enhancing PHP-based WordPress Weblog with AJAX driven enrichments

Over the past period I have written several articles on AJAX – the Asynchronous JavaScript and XML mechanism for dynamically updating a web-page based on background communication with the server. Now I have applied those concepts to our own WebLog.

Since last Wednesday, the left column of the AMIS Technology Weblog displays some statistics: the number of Post Reads that we have had since the start of the weblog, July 2004, and the number of Unique Visitors (IP addresses) we have had during the current day. Note: our day starts at 12PM (UTC)+1.
Enhancing PHP-based Wordpress Weblog with AJAX driven enrichments
It turned out that directly adding this information to the page would slow down the weblog: it would take several seconds for the pages of the weblog to build, as before the response was sent to the client, the two database queries behind the statistics had first to be executed.

Therefore, I changed tack. Now the page is sent to the browser as it was before. It does however contain a small DIV element, that is initially hidden.

 <li id="about">About:
 <ul>
    <li>The Amis technology corner comprises Amis' activities, sources, tools, articles and presentations on ICT subjects our technical experts are dealing with on a daily basis.</li>
 </ul>
 </li>
 <li id="statistics">
   <div id="stats" style="display:none">
     Statistics:
     <ul>
       <li>Total post reads:
         <span id="postreads">
           ...
         </span>
       </li>
       <li>Post reads today:
         <span id="todaysreads">
           ...
         </span>
       </li>
     </ul>
   </div>
 </li>
 <li id="search">

When the page is loaded, AJAX fuelled logic kicks in to start up a background communication with the server to retrieve the statistics. This is triggered from the onLoad event on the BODY element:

<body onLoad="ajaxStats()" >

The client side logic looks like this:

	<script language="JavaScript">
   var xmlHttpRequest; // global variable, the xmlHttpRequest object that used for AJAX
  function ajaxStats()
  {
     var callback = processTotalReadsRequestChange;
     // invoke server side PHP to return the numbers
     // after that, call displayStats to make stats visible
     // create the object, careful to the MSFT/Other method
    if (window.XMLHttpRequest) // Mozilla and FireFox
    {
      xmlHttpRequest = new XMLHttpRequest();
      // executing the request, passing the targetted object
      xmlHttpRequest.open("GET", "postreads.php", true); // true indicates ASYNCHRONOUS processing; false would mean SYNCHRONOUS
      xmlHttpRequest.onreadystatechange = callback;
      xmlHttpRequest.send(null);
    }
    else if (window.ActiveXObject) // Internet Explorer
    {
      xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
      // executing the request, passing the targetted object
      xmlHttpRequest.open("GET", "postreads.php", true); // true indicates ASYNCHRONOUS processing; false would mean SYNCHRONOUS
      xmlHttpRequest.onreadystatechange = callback;
      xmlHttpRequest.send();
    }
  }//ajaxStats
   /**
   * Handle the events of the XMLHttpRequest Object
   */
   function processTotalReadsRequestChange()   {
     obj=document.getElementById("postreads");
     if (xmlHttpRequest.readyState ==4)
     {
       if(xmlHttpRequest.status  ==200)
       {
         myTextNode=document.createTextNode(xmlHttpRequest.responseText);
         obj.removeChild(obj.childNodes[0]);
         obj.appendChild(myTextNode);
         displayStats();
         // invoke ajaxTodayStats() to also display the post reads so far today
         ajaxTodayStats();
       }
     }
   }//processTotalReadsRequestChange
  function ajaxTodayStats()
  {
     var callback = processTodayReadsRequestChange;
     // invoke server side PHP to return the numbers
     // after that, call displayStats to make stats visible
     // create the object, careful to the MSFT/Other method
    if (window.XMLHttpRequest) // Mozilla and FireFox
    {
      xmlHttpRequest = new XMLHttpRequest();
      // executing the request, passing the targetted object
      xmlHttpRequest.open("GET", "todaysreads.php", true); // true indicates ASYNCHRONOUS processing; false would mean SYNCHRONOUS
      xmlHttpRequest.onreadystatechange = callback;
      xmlHttpRequest.send(null);
    }
    else if (window.ActiveXObject) // Internet Explorer
    {
      xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
      // executing the request, passing the targetted object
      xmlHttpRequest.open("GET", "todaysreads.php", true); // true indicates ASYNCHRONOUS processing; false would mean SYNCHRONOUS
      xmlHttpRequest.onreadystatechange = callback;
      xmlHttpRequest.send();
    }
  }//ajaxStats
   /**
   * Handle the events of the XMLHttpRequest Object
   */
   function processTodayReadsRequestChange()   {
     obj=document.getElementById("todaysreads");
     if (xmlHttpRequest.readyState ==4)
     {
       if(xmlHttpRequest.status  ==200)
       {
         myTextNode=document.createTextNode(xmlHttpRequest.responseText);
         obj.removeChild(obj.childNodes[0]);
         obj.appendChild(myTextNode);
       }
     }
   }//processRequestChange
  function displayStats()
  { //make the stats element (DIV) visible
    obj=document.getElementById("stats");
    obj.style.display=( (obj.style.display=='none') ? '' : 'none');
  }
</script>

The JavaScript AjaxStats() function builds an XmlHttpRequest object and sends a request to the relative URL: postreads.php. This PHP file is on the server and returns a text-document with the number of post reads of all time:

    <?php $postreads = $wpdb->get_var("SELECT count(*) FROM wp_dstats2 WHERE page = '$post_ID' LIMIT 1"); ?>

    <fieldset id="poststatsdiv">
      <legend>Post Statistics</legend>
	  <div>Post Reads: <?php echo $postreads ?></div>
    </fieldset>

When the response from this PHP is in, the browser calls the function processTotalReadsRequestChange() . This function gets the result from the response – xmlHttpRequest.responseText – and adds it as new TextNode to the DIV element with ID=postreads. Then the DIV with ID=stats is made visible. At that point, you can see the first statistic: the total number of post reads.

Enhancing PHP-based Wordpress Weblog with AJAX driven enrichments

Next, there is a call to the function ajaxTodayStats(). This function starts another AJAX exchange, to retrieve the number of postreads of the day, using the PHP todaysreads.php:

<?php
/* Don't remove this line. */
require('./wp-blog-header.php');
?>
<?php $todayreads = $wpdb->get_var("select  count(time) from wp_dstats2, wp_posts  where wp_dstats2.page = wp_posts.ID and date_format(time,'%Y.%d.%m') = date_format(now(),'%Y.%d.%m')"); ?>
<?php echo $todayreads ?>

Of course, if we want to display additional statistics, we can go on calling server side queries through AJAX, gradually building the list of statistics in the WebLog.

2 Comments

  1. Alec November 22, 2006
  2. Zeger Hendrikse September 20, 2005