Page And Block Caching

Photo of Greg Harvey
Tue, 2008-12-23 12:53By greg

I had an issue the other day born out of a misconception about the way block and page caching works. I created a Known User Role module, which includes a block saying something like "Welcome back, !username" to so-called "known" users. I created it on my development Drupal site with caching Disabled (at admin/settings/performance) and it worked great. I implemented this in hook_block(), which I presumed would exclude this dynamic block from all caches:

if ($op == 'list') {
$blocks[0]['info'] = t('Known user login');
$blocks[0]['cache'] = BLOCK_NO_CACHE;
return $blocks;
}
?>

However, with Drupal caching set to Normal I was experiencing caching problems, in spite of the BLOCK_NO_CACHE line (anonymous users would be welcomed back as though they were someone else). This is because there is a fundamental difference between block and page caching - while there are some simple caching choices you can make from the block module as to how and when blocks are cached in the page cache, the page cache itself has utterly no awareness of the block cache. It is quite "stupid", for want of a better word. It saves a simple snapshot of the current page to be shown to anonymous users later.

If page cache is enabled then blocks *will* be cached, regardless of block cache settings in hook_block(). The PHP above simply means if page caching is disabled the block caching engine will not cache that block. There is absolutely nothing you can do to exclude a block from the page cache. It fundamentally does not work like that.

I am currently debating the idea of getting around this by offering the option in admin of clearing the cache on page load for known user, so site admins who don't mind the performance hit can still use the feature. It's more of a problem for projects like Ecommerce and Ubercart, who might want to show a dynamic shopping basket for anonymous users. This sort of thing won't work. =(