4

Caching in Drupal 8 is great, but documentation is thin (at this time) on using cache tags for render arrays in Drupal 8.

I have some code that basically generates a list of node teasers, say for content types "books" and "magazines". I'm caching the list to speed things up. I would like to refresh the list every time a "book" or "magazine" is added/deleted/edited. So I have a render array that looks like this:

$build = array(
  '#type' => 'markup',
  '#markup' => $sMarkup,        
  '#cache' => [
    'keys' => ['home-all','home'],
    'tags'=> ['node_list'], // invalidate cache when any node content is added/changed etc.
    'max-age' => '36600', // invalidate cache after 10h
  ],
);

By using the cache tag ['node_list'], the cache invalidates properly when content is added or edited, but will also invalidate when a content type not being listed here is changed, say "casette".

What cache tags can I use to limit the invalidation to when only "book" or "magazine" is added/changed/deleted? I've tried using: ['book_list','magazine_list'] but that doesn't work.

3 Answers 3

6

Starting Drupal 8.9.0, there is a new ENTITY_TYPE_list:BUNDLE cache tag added (see the change record).

So in your case you would simply need to tag our list with node_list:book.

https://www.drupal.org/node/3107058

0
4

In this case I know two options.

One - Include all node tags (node:{#id}), if doesn't matter if a new node of a particular type was added.

Two - Create and control your own cache tag, and invalidade it when you want.

I'm developing a site that was needed create a term list cache per vocab_id. In this case every time that a term from a particular vocab_id change/add/delete the cache tag is invalided using Cache::invalidateTags($tag_id) then my block will be rebuild.

Edit 1

Example:

use Drupal\Core\Cache\Cache;

function filters_invalidate_vocabulary_cache_tag($vocab_id) {
  Cache::invalidateTags(array('filters_vocabulary:' . $vocab_id));
}

In your case maybe is just change $vocab_id for $node_type.

3
  • Thanks @vagner - I've started going down option 2, because I need to refresh when a new node is added. Having troubles invalidating the tags though, trying like this: \Drupal\Core\Cache\CacheTagsInvalidator::invalidateTags(["myTag"]); - which gives an error
    – ryrye
    Commented May 6, 2016 at 17:49
  • @ryrye added an example.
    – Vagner
    Commented May 6, 2016 at 18:03
  • 1
    CacheTagsInvalidator is a service that Cache:: wraps. You can also use that, especially in a controller/service, but then you have to call it on the cache tags invalidator service. Also, see drupal.org/project/views_custom_cache_tag if you want to use this approach with views.
    – Berdir
    Commented May 8, 2016 at 14:40
1

See the contrib module handy_cache_tags. I haven't used it (yet), but it purports to do exactly what you are looking for. From the module's description:

The module provides the following cache tags for you to use:

handy_cache_tags:[entity_type]
handy_cache_tags:[entity_type]:[entity_bundle]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.