部分缓存成员

时间:2013-03-06 20:34:24

标签: silverstripe

我正在使用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 %>

我有两个问题:

  1. 根据上面的缓存键,如果授权成员是第一个查看页面的人,那么页面将被缓存,并且在后续页面视图中会向非成员显示独占材料。

  2. 如果我将缓存键调整为以下内容:

    <% cached 'items', Items.max(Created), CacheSegment unless CurrentMember %>
        <% loop $Items %>
            $Me
        <% end_loop %>
    <% end_cached %>
    
  3. 然后,每个$ Me模板中的内容永远不会被缓存为成员 - 这是我网站查看者中最大的部分。

    有没有办法可以为成员和非成员缓存$ Items列表,并且仍然能够在循环中对$ Item使用HasAccess检查?

1 个答案:

答案 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 %>

在某个地方有比这更好的解决方案,但它会起作用。