20

I would like to use the new Cache Tagging in D8 to help keep related content of different types (entities, nodes, blocks, etc) in sync. But from reading the currently available documentation of this feature I do not understand how to add my own cache tag to the items of content when creating/updating said items.

For example when creating a new node of an type Store I would like to add the cache tag location:new_york_123 and the same for a a block. Then if I changed the display name of the New York 123 location to SoHo, I could invalidate the cache tag and have all related content update.

4
  • 2
    All entities already have a cache tag (e.g. node:123) that is automatically invalidated. So if you're just creating/updating and displaying nodes, you shouldn't have to do anything, it should just work.
    – Berdir
    Commented Jul 18, 2016 at 18:30
  • 1
    upon create/update it would require a query to find all related types of content (nodes, blocks, entities) and then clear them from each cache table. If a single custom cache tag is used to identify the relationship of the content items only that tag would need to be invalidated to clear the cache of those related items. Commented Jul 18, 2016 at 18:36
  • 1
    I don't understand what you mean and what your structure is. Tags are added when they are used. Cache tags should be added to any render element like a block if it needs to change if that node/thing is changed. If you use standard mechanisms to display entities, then that's likely already the case. If it doesn't work, you need to share in more detail, with code, what exactly you are doing.
    – Berdir
    Commented Jul 18, 2016 at 18:39
  • 1
    cache tag user:{ID} could be invalidated to trigger the cache clear for all content related to that user. Same idea, but with the custom cache tag. Commented Jul 18, 2016 at 18:46

1 Answer 1

19

Here is how to use cache tags in the context of custom blocks which I have tried and works but I think it applies to other contexts

Use default drupal tags

In the build array you can specify cache > tags > node_list and this block content would get invalidated (refreshed) when ANY NODE is changed with nothing else to do on your part

public function build() {
    return array(
        '#markup' => MY_MODULE_awesome_dynamic_node_content(),
        '#cache' => [
            'tags' => ['node_list'], //invalidate when any node updates
            //'tags' => ['node:1','term:2'], //invalidate when node 1 or term 2 updates
        ],
    );
}

Alternatively you can put in one or more node/term/user IDs to invalidate the array on specific nodes or terms as shown in the code comment above. Note: you can mix and match nodes, terms, users and custom tags as you see fit.

Use your own tags

if you want to have your own way of clearing your build array add your custom unique tag in the build array (any unique string will do)

public function build() {
    return array(
        '#markup' => MY_MODULE_awesome_dynamic_node_content(),
        '#cache' => [
            'tags' => ['MY_CUSTOM_UNIQUE_TAG'],
        ],
    );
}

and in your custom code logic call invalidateTags with your own tag

function MY_MODULE_custom_clear_cache_logic(){ 
    ...
    \Drupal\Core\Cache\Cache::invalidateTags(array('MY_CUSTOM_UNIQUE_TAG'));        

if you want to read more about drupal 8 cache internals

4
  • 3
    I think ideally you'd use the cache_tags.invalidator service rather than referencing a class directly.
    – Andy
    Commented Jun 25, 2018 at 9:40
  • When we talk about a node ID in this context, are we literally talking about a node ID, or are actually referring to the machine name of a content type? The core documentation is completely unclear about this. What I'd like to do is invalidate a content type not just one node. Commented Feb 16, 2021 at 22:19
  • @Andy - Since Cache::invalidateTags simply loads the cache_tags.invalidator service and executes its invalidateTags() method, it might be clearer to say use the service in a context where it can be injected and use the class when it can't, such as in the example given. Commented Mar 16, 2021 at 15:24
  • 1
    @maskedjellybean - Probably properly asked as it's own question, but "node id" means an integer identifying a particular node, internally usually nid. If you want cache tags on all nodes of a particular bundle, try the handy cache tags modules: drupal.org/project/handy_cache_tags. Commented Mar 16, 2021 at 15:29

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.