Skip to content

Instantly share code, notes, and snippets.

@crittermike
Last active October 23, 2020 17:42
Show Gist options
  • Save crittermike/71eab7bb9fcf0666e8eac0d1f88bbae4 to your computer and use it in GitHub Desktop.
Save crittermike/71eab7bb9fcf0666e8eac0d1f88bbae4 to your computer and use it in GitHub Desktop.
Drupal 8 block with custom cache context and tags
<?php
class MyCustomBlock extends BlockBase {
public function build() {
return array(
'#markup' => $this->t('My custom block content'),
'#cache' => array(
'contexts' => ['url.path'], // https://www.drupal.org/developing/api/8/cache/contexts
'tags' => ['node:1', 'node:2'] // https://www.drupal.org/developing/api/8/cache/tags
),
);
}
}
@crittermike
Copy link
Author

crittermike commented Jul 26, 2016

Note that ENTITYNAME_list such as node_list are appropriate tag names as well, which invalidate whenever any entity of that type is added/edited/deleted.

Instead of hardcoding ENTITYTYPE_list, you can find it by calling the function that provides them:

\Drupal::entityManager()->getDefinition('ENTITYTYPE')->getListCacheTags(),

In most cases, that will just return "ENTITYTYPE_list" but not necessarily always, if a given entity class has overridden its $this->list_cache_tags property.

@innoraft12
Copy link

Here is an example from a custom block in Drupal 8:
use Drupal\Core\Cache\Cache;

return [
'#theme' => 'user_profile_template',
'#user_data' => $user_data,
'#cache' => [
'tags' => ['languages', 'timezone'],
'contexts' => ['node:5', 'user:3'],
'max-age' => Cache::PERMANENT,
],
];

We can also define our own cache tag:
Request a cache object through \Drupal::cache().
Define a Cache ID (cid) value for your data. A cid is a string, which must contain enough information to uniquely identify the data.
Call the get() method to attempt a cache read, to see if the cache already contains your data.
If your data is not already in the cache, compute it and add it to the cache using the set() method.
$nid = 9;
$cid = 'my_module:' . $nid;

// Check if the cache already contain data.
if ($item = \Drupal::cache()->get($cid)) {
return $item->data;
}

// The data to be cached.
$node = Node::load($nid);
$data = [
'title' => sprintf('## %s', $node->get('title')->getValue()),
//...
];

// Set the cache for 'my_module:' . $nid cache tag until $node changes.
\Drupal::cache()->set($cid, $data, Cache::PERMANENT, $node->getCacheTags());

Check out How does entity cache work in Drupal 8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment