Home > Tools > CMS > Drupal > Drupal Hacks > More on Clearing Drupal's Page Cache

More on Clearing Drupal's Page Cache

Recently I wrote an article where I explained how to clear page cache entries in Drupal when content is commented on. This time I want to clear entries in the cache_page database table when the following conditions apply:

  1. A new node is created, set to published and promoted to the front page.
  2. A published node which is promoted to the front page is deleted.
  3. A published node which is promoted to the front page is unpublished.
  4. A node which is promoted to the front page is unpublished.
  5. A published node is updated.

When one of the conditions 1 - 4 applies the page_cache entry for the front page is to be deleted. When the 5th condition applies the page_cache for the node itself is to be deleted.

To achieve this functionality in Drupal 5, I implement the hook_nodeapi() function in my custom.module and add the function custom_clear_front_page_cache() for deleting the front page cache entries.

The custom_nodeapi() function checks whether the conditions described above apply and deletes the cache entries by calling the cache_clear_all() and the custom_clear_front_page_cache() functions:

<?php
function custom_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  switch (
$op) {
    case
'insert':
    case
'delete':
     
// clear the front page cache_page entry if node is promoted
      // and published or deleted
     
if ($node->status && $node->promote) {
       
custom_clear_front_page_cache();
      }
      break;
    case
'update':
     
// clear the cache_page entry of the updated if it is published
     
if ($node->status) {
       
$url = url('node/'. $node->nid, NULL, NULL, TRUE);
       
cache_clear_all($url, 'cache_page');
      }
     
// clear the front page cache_page entry if node is unpublished
     
if (!$node->status && $node->promote) {
       
custom_clear_front_page_cache();
      }
      break;
  }
}
?>

The custom_clear_front_page_cache() function first retrieves the value of Drupal's system variable site_frontpage generates the absolute URL for the corresponding page and deletes the appropriate entry in the cache_page database table.

By default the value of site_frontpage is set to node, which is also the case on SEO Expert Blog. The deleted cache entrie's cid value is http://www.seo-expert-blog.com/node. The problem is that there is also a cache entry with the cid http://www.seo-expert-blog.com/ with a trailing slash.

To also delete this entry, the cache_clear_all function is called again with the URL stripped off the final site_frontpage string value:

<?php
function custom_clear_front_page_cache() {
 
$front = variable_get('site_frontpage','node');
 
$url = url($front, NULL, NULL, TRUE);
 
cache_clear_all($url, 'cache_page');
 
$url = preg_replace("%$front$%", '', $url);
 
cache_clear_all($url, 'cache_page', FALSE);
}
?>

Again, thanks to the geniuses behind Drupal, very few lines of PHP code achieve the desired functionality. One of the benefits of doing this, when caching is enabled, is that visitors who are not logged in, will see new content that is promoted to the front page immediately after it is inserted in the database.

Hi. Is there a way to do this under Drupal 4.7?

In Drupal 4.7 the cache_clear_all() function isn't called with a table name as the 2nd argument, but the rest should work the same.

Hi, I'm a little new to drupal...I have basic PHP and MySQL. Could you tell me how to go about integrating this function into my site? Many thanks.

Copy and paste the example code in a file called custom.module and save it in the directory where you store contrib modules, e.g. /sites/all/modules. You will also need an info file called custom.info. See the drupal.org documentation on info files.

Do you why such a thing isn't already included in Drupal? Especially the comment page cache expiration. Do you know if it will be included?

I don't think this will be included, because for high traffic sites this may not be the best behavior. But it could be added as a setting so admins can choose whether to clear cache after comments are posted or not.

Has anyone tried it in Drupal 4.7?