1

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

然后每个 $Me 模板中的内容永远不会为成员缓存 - 这是我网站查看者的最大部分。

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

4

1 回答 1

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

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

于 2013-03-07T05:48:46.040 回答