Drupal 8:修改关联内容类型后自动清除渲染缓存的代码实现求助
解决Drupal 8中节点修改后自动清除关联缓存的方案
我之前也碰到过这种跨实体引用导致的缓存不同步问题——当节点关联的分类术语又被其他节点引用时,默认的缓存机制不会自动触发关联页面的缓存失效,必须手动清render缓存。下面给你一个自定义模块的实现方案,完全通过后端代码解决,不需要碰Twig:
1. 创建自定义模块
首先我们需要一个简单的自定义模块,比如命名为custom_cache_clear,步骤如下:
1.1 模块配置文件(info.yml)
在modules/custom/custom_cache_clear目录下创建custom_cache_clear.info.yml,内容如下:
name: Custom Cache Clear type: module description: 自动清除节点更新时关联内容的缓存,解决跨实体引用的缓存不同步问题 core_version_requirement: ^8 || ^9 || ^10 package: 自定义
1.2 模块逻辑文件(.module)
同目录下创建custom_cache_clear.module,写入以下代码:
<?php /** * Implements hook_node_update(). * 当节点更新时触发,清除关联分类术语的所有引用节点的缓存 */ function custom_cache_clear_node_update(\Drupal\node\NodeInterface $node) { // 配置你需要处理的内容类型和分类字段 $target_content_types = ['page']; // 替换成你的目标内容类型机器名 $taxonomy_field_name = 'field_category'; // 替换成节点上的分类引用字段机器名 // 检查当前更新的节点是否属于目标类型,且包含指定分类字段 if (!in_array($node->bundle(), $target_content_types) || !$node->hasField($taxonomy_field_name)) { return; } // 获取当前节点关联的所有分类术语 $related_terms = $node->get($taxonomy_field_name)->referencedEntities(); if (empty($related_terms)) { return; } foreach ($related_terms as $term) { // 查询所有引用该分类术语的已发布节点 $referenced_node_ids = \Drupal::entityQuery('node') ->condition($taxonomy_field_name, $term->id()) ->condition('status', 1) ->execute(); if (!empty($referenced_node_ids)) { // 1. 重置节点实体缓存 \Drupal::entityTypeManager()->getStorage('node')->resetCache($referenced_node_ids); // 2. 失效对应节点的render缓存标签 $cache_tags = array_map(function($nid) { return "node:$nid"; }, $referenced_node_ids); \Drupal::service('cache_tags.invalidator')->invalidateTags($cache_tags); } } // 如果你确实需要清除全部render缓存(不推荐,会影响性能),可以取消下面的注释 // \Drupal::service('cache.render')->invalidateAll(); }
2. 代码说明
- 这段代码通过
hook_node_update钩子,在节点更新时自动触发逻辑; - 首先过滤出你需要处理的内容类型和分类字段,避免不必要的性能消耗;
- 获取当前节点关联的分类术语,然后查询所有引用这些术语的已发布节点;
- 先重置节点实体缓存,再通过缓存标签失效机制清除对应的render缓存,确保关联页面下次访问会重新渲染;
- 如果你的场景更复杂(比如多个分类字段、跨内容类型引用),可以调整
$target_content_types和$taxonomy_field_name,或者扩展查询条件。
3. 启用模块
把这个模块放到modules/custom目录下,然后在Drupal后台的模块管理页面启用它,之后再修改节点时,关联的页面缓存就会自动失效了。
内容的提问来源于stack exchange,提问作者Aadil Naik
相关产品推荐
相关产品推荐

