我尝试在不使用块可见性插件的情况下进行设置,它对用户有效,但在内部我希望通过使用我自己的缓存标签来更好地控制。
我的问题是我似乎无法找到将缓存标签注入块的正确组合,以便稍后能够使其无效。我已经尝试了各种块挂钩,到目前为止 kernel.request 和 kernel.finish_request 事件。后者在挂钩之后仍然使缓存无效(当我一般这样做时,即不使用我自己的缓存标签),所以这是一个好的开始。
总体目标是能够交替用户在同一页面上的后续页面视图中看到的块。因此,比如说主页,第一个视图可能会显示块 A,下一个视图可能会显示块 B,第三个块 C,然后返回块 A,依此类推。
关闭缓存(即在开发模式下),它可以正常工作。另外,在不参考我自己的标签的情况下使缓存失效,并使用正常的缓存也可以正常工作。但是,我想使用我自己的缓存标签来做到这一点。
要显示哪个块的选择是在 hook_block_access() 挂钩中确定的,因此我必须在此事件之前准备好设置。
如果这不是一个好主意,我愿意采用不同的方法来使用块钩子,因此欢迎其他想法。然而,如果只是我需要调整一些东西并且它会起作用,那就更好了。
我使用 hook_block_view_alter() 而不是早期钩子的原因是因为在此之前我注意到早期钩子中的块 ID 可能还不存在(或者可能我错过了一些东西,如果是这样请纠正我),我需要区块 ID。
以下是我到目前为止所拥有的。
// In the .module file...
/**
* Implements hook_block_view_alter().
*/
function my_module_block_view_alter(array &$build, BlockPluginInterface $block) {
// 3rd hook to get called in the block hooks
if (array_key_exists('#id', $build) ) {
$ci = MyController::getInfo($build['#id']);
if ($ci['CanControl'] !== []) {
$controlId = &$ci['CanControl']['id'];
$build['#cache']['tags'][] = $controlId;
$build['#cache']['tags'][] = "$controlId:$build[#id]");
}
}
}
// In an event subscriber module off the kernel.FinishRequest event.
class BlockCacheManager implements EventSubscriberInterface {
// EVENT SUBSCRIBER STUFF THEN...
public function kernelFinishRequest(Event $event) {
// Ignore AJAX calls
if (!Drupal::request()->isXmlHttpRequest()) {
// CODE THAT GETS THE RELEVANT BLOCK IDs THEN...
$blocks = Block::loadMultiple($blockIds);
$tags = [];
foreach ($blocks as $block) {
$bTags = $block->getCacheTagsToInvalidate(); // My tags are not here
$bTags2 = $block->getCacheTags(); // nor here
$tags = array_merge($tags, $block->getCacheTagsToInvalidate());
}
// What I would like to to do is below but my tags don't show up with
// $block->getCacheTags() or $block->getCacheTagsToInvalidate() as
// indicated above.
foreach ($blockIds as $blockId) {
$cacheTags[] = "$controlId:$build[#id]";
}
}
}
}
我在 drupal.org 上发现这篇文章,表明更改该挂钩中的缓存的功能已被删除。
这篇文章专门讨论了上下文缓存而不是标签,但我怀疑这会是相同的结果,所以我放弃尝试这样做,除非有人表明这是可能的。