2013-03-06 30 views
1

我正在使用DataObjectsAsPage模塊。它將一個Datalist($ Items)返回到循環遍歷每個$ Item的持有者頁面。我也試圖爲頁面開發部分緩存策略。我在,你不能把一個循環內緩存塊的文檔閱讀,所以在我的DataObjectsAsPageHolder頁,我有以下幾點:部分緩存成員

<% cached 'items', LastEdited, CacheSegment %> 
    <% loop $Items %> 
     $Me 
    <% end_loop %> 
<% end_cached %> 

我查了silverstripe緩存/緩存目錄,這似乎是緩存$項目列表。

問題是我已經爲每個$ Item添加了一個DataExtension,允許管理員根據CurrentMember的組來設置是否可以查看$ Item。因此,在每個$我的模板,我有以下幾點:

<% if HasAccess %> 
<% end_if %> 

我有兩個問題:

  1. 鑑於上述緩存鍵,如果授權的成員是查看網頁的第一,那麼頁面獲取緩存並且獨佔材料在隨後的頁面瀏覽中顯示給非成員。

  2. 如果我調整緩存項設置爲以下:

    <% cached 'items', Items.max(Created), CacheSegment unless CurrentMember %> 
        <% loop $Items %> 
         $Me 
        <% end_loop %> 
    <% end_cached %> 
    

然後在每個$我的模板的內容是不會被緩存的成員 - 這是我的地盤觀衆的最大部分。

有沒有一種方法可以緩存成員和非成員的$ Items列表,並且仍然可以在循環中使用$ Item的HasAccess檢查?

回答

3

最簡單的解決方案可能是將當前成員的ID添加到緩存鍵。

<% cached 'items', LastEdited, CacheSegment, CurrentMember.ID %> 
    <% loop $Items %> 
     $Me 
    <% end_loop %> 
<% end_cached %> 

但是,這將緩存每個註冊成員的唯一塊。爲了使緩存更有用,您應該使用緩存鍵中的當前成員組。不幸的是,我不知道爲成員獲取模板緩存鍵準備好的組列表。

獲得圍繞此問題的最簡單方法可能是爲Page類添加GroupsCacheKey函數。這是一個骯髒的解決方案,但它應該有效地工作。

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

沒有比這一點有沒有更好的解決方案的地方,但它會奏效。

+0

第二種解決方案適用於我的情況。所需的唯一更改是將asArray方法更改爲toArray。除此之外,我一直在測試我的緩存頁面,並且類似組的成員正在服務於它們各自的緩存頁面。非常感謝您的幫助! – 2013-03-07 15:37:49

+0

糟糕。正如我所說,未經測試。上面的答案已經修正 – drzax 2013-03-07 22:59:42