Drupal 9:无需清缓存即可获取当前IP并更新视图默认筛选值
解决方案
问题根源在于你仅针对节点配置了缓存禁用,但视图(尤其是以块形式渲染的视图)拥有独立的缓存机制,需要针对视图本身配置缓存上下文与过期策略,才能让默认筛选值随IP变化实时更新。
1. 核心修复:配置视图缓存规则
修改MYMODULE_views_pre_build函数,添加基于IP的缓存上下文,并设置缓存过期时间,让Drupal感知到视图输出依赖用户IP:
function MYMODULE_views_pre_build(ViewExecutable $view) { if(($view->id() === 'myview_id') && ($view->current_display === 'block_1')) { // 配置缓存上下文:基于用户IP,确保不同IP生成独立缓存版本 $view->getDisplay()->setOption('cache_contexts', ['ip']); // 设置缓存过期时间:立即过期(若允许短时间缓存可设为300秒即5分钟) $view->getDisplay()->setOption('cache_max_age', 0); // 原有业务逻辑保留,替换IP获取方式为Drupal标准API $exposed_input = $view->getExposedInput(); $currentIP = \Drupal::request()->getClientIp(); $ipdat = json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $currentIP)); $currentCountry = $ipdat->geoplugin_countryName; $fieldName = 'field_myfield_target_id'; // 统一字段名,修正原代码分支不一致问题 if($currentCountry=='India') { $exposed_input[$fieldName] = 26; } elseif($currentCountry=='Russia') { $exposed_input[$fieldName] = 174; } else { $exposed_input[$fieldName] = 26; } $view->setExposedInput($exposed_input); } }
2. 移除无效节点缓存代码
你之前编写的MYMODULE_node_view仅对ID为144的节点生效,但视图块是独立渲染元素,不受节点缓存设置影响,可直接删除这段代码。
3. 可选优化:缓存地理查询结果
频繁调用外部地理API会影响性能,可给IP查询结果添加基于IP的本地缓存:
// 替换原函数中的IP查询部分 $currentIP = \Drupal::request()->getClientIp(); $cacheKey = 'geolocation_country_' . $currentIP; $cache = \Drupal::cache()->get($cacheKey); if ($cache && !empty($cache->data)) { $currentCountry = $cache->data; } else { $ipdat = json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $currentIP)); $currentCountry = $ipdat->geoplugin_countryName; // 缓存24小时,可按需调整时长 \Drupal::cache()->set($cacheKey, $currentCountry, time() + 86400); }
关键说明
- 缓存上下文
ip:让Drupal为不同IP生成独立缓存版本,VPN切换IP后自动触发新缓存生成。 cache_max_age=0:强制视图不缓存,每次请求重新计算默认值;若允许短时间缓存,可设置为300秒平衡性能与实时性。- 统一字段名:修正原代码else分支字段名不一致的逻辑错误。
内容的提问来源于stack exchange,提问作者Souvik Das
相关产品推荐
相关产品推荐

