我正在使用DataObjectsAsPage模块。它将一个Datalist($ Items)返回到持有者页面,该页面遍历每个$ Item。我也在尝试为页面开发部分缓存策略。我在文档中读到你不能将缓存块放在循环中,所以在我的DataObjectsAsPageHolder页面中,我有以下内容:
<% cached 'items', LastEdited, CacheSegment %>
<% loop $Items %>
$Me
<% end_loop %>
<% end_cached %>
我检查了silverstripe-cache / cache目录,这似乎是缓存$ Items列表。
问题是我已经为每个$ Item添加了一个DataExtension,允许管理员根据CurrentMember的组来设置$ Item是否可见。因此,在每个$ Me模板中,我有以下内容:
<% if HasAccess %>
<% end_if %>
我有两个问题:
根据上面的缓存键,如果授权成员是第一个查看页面的人,那么页面将被缓存,并且在后续页面视图中会向非成员显示独占材料。
如果我将缓存键调整为以下内容:
<% cached 'items', Items.max(Created), CacheSegment unless CurrentMember %>
<% loop $Items %>
$Me
<% end_loop %>
<% end_cached %>
然后,每个$ Me模板中的内容永远不会被缓存为成员 - 这是我网站查看者中最大的部分。
有没有办法可以为成员和非成员缓存$ Items列表,并且仍然能够在循环中对$ Item使用HasAccess检查?
答案 0 :(得分:3)
最简单的解决方案可能是将当前成员的ID添加到缓存键。
<% cached 'items', LastEdited, CacheSegment, CurrentMember.ID %>
<% loop $Items %>
$Me
<% end_loop %>
<% end_cached %>
但是,这将为每个注册成员唯一缓存块。要使缓存更有用,您应该使用缓存键中的当前成员组。不幸的是,我知道没有简单的方法来获取成员的模板缓存密钥就绪列表。
解决此问题的最简单方法可能是向GroupsCacheKey
课程添加Page
功能。这是一个肮脏的解决方案,但它应该有效。
// Untested function
public function GroupsCacheKey() {
if ($member = Member::currentUser()) {
return implode('', $member->Groups()->map('ID', 'ID')->toArray());
}
return 'nonmember';
}
然后在你的模板中:
<% cached 'items', LastEdited, CacheSegment, GroupsCacheKey %>
<% loop $Items %>
$Me
<% end_loop %>
<% end_cached %>
在某个地方有比这更好的解决方案,但它会起作用。