13

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.

  • 1
    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 Jul 18 '16 at 18:30
  • 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. – LittleCoding Jul 18 '16 at 18:36
  • 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 Jul 18 '16 at 18:39
  • 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. – LittleCoding Jul 18 '16 at 18:46
12

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

  • 2
    I think ideally you'd use the cache_tags.invalidator service rather than referencing a class directly. – Andy Jun 25 '18 at 9:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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