You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:01:02