When returning info for a custom block we can specify what kind of caching that will be used for the block according to the values in: hook_block_info()
.
Notice that if the block is cached the hook_block_view()
will not be called at all.
In a module I'm developing I would like the user to be able to set the expiration time for the block cache, so I have tried something like this:
/**
* Implements hook_block_info().
**/
function CUSTOM_MODULE_block_info() {
return array(
'custom_block' => array(
'info' => t('Custom Block'),
'cache' => DRUPAL_NO_CACHE,
),
);
}
/**
* Implements hook_block_configure().
**/
function CUSTOM_MODULE_block_configure($delta = '') {
$form = array();
$form['custom_module_cache_expire'] = array(
'#type' => 'textfield',
'#title' => t('Cache expire'),
'#default_value' => variable_get('custom_module_cache_expire', 0),
);
return $form;
}
/**
* Implements hook_block_view().
**/
function CUSTOM_MODULE_block_view($delta = '') {
$block = array();
if ($delta == 'custom_block') {
$cache = &drupal_static(__FUNCTION__);
if (empty($cache)) {
// Try to get data from cache.
$cache = cache_get('custom_module');
if (!empty($cache->data)) {
// Check the expiration time.
if (time() > $cache->expire) {
// Remove the cache.
cache_clear_all('custom_module');
}
$block = $cache->data;
}
else {
// Build the renderable array and cache the result for 5 minutes.
// The 'custom_module_get_items()' is a long running task and
// the reason why we want to cache this block at a certain interval.
$block['content'] = array(
'#items' => custom_module_get_items(),
);
cache_set('custom_block', $block, 'cache', time() + (60 * 5));
}
}
else {
$block = $cache->data;
}
}
return $block;
}
The above almost works as expected, but I was wondering if there some better way of doing this.
In Drupal 8 we can use the cache max-age
to achieve this behavior.
I also tried to set the cache
in the renderable array for the block, but I'm not sure what this does actually:
$block['content'] = array(
'#items' => custom_module_get_items(),
'#cache' => array(
'expire' => time() + (5 * 60),
),
);
Perhaps the best way would be to simply set the caching to DRUPAL_NO_CACHE
for the block and then in custom_module_get_items()
use cache_set()
and cache_get()
?
I was also thinking that another way of doing this might be to just remove the default block cache from the database at a specific interval?