【问题标题】:Partial Cache Members部分缓存成员
【发布时间】:2013-03-06 20:34:24
【问题描述】:

我正在使用 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 检查?

【问题讨论】:

    标签: silverstripe


    【解决方案1】:

    最简单的解决方案可能是将当前成员的 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 %>
    

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

    【讨论】:

    • 第二种解决方案非常适合我的情况。唯一需要的更改是将 asArray 方法更改为 toArray。除此之外,我一直在测试我的缓存页面,并且正在为类似组的成员提供各自的缓存页面。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多