1

私は DataObjectsAsPage モジュールを使用しています。各 $Item をループするホルダー ページに Datalist ($Items) を返します。また、ページの部分的なキャッシュ戦略を開発しようとしています。ループ内にキャッシュ ブロックを配置できないというドキュメントを読んだので、DataObjectsAsPageHolder ページに次のように記述しました。

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

silverstripe-cache/cache ディレクトリを確認したところ、これは $Items リストをキャッシュしているようです。

問題は、CurrentMember のグループに基づいて $Item が表示可能かどうかを管理者が設定できるように、各 $Item に DataExtension を追加したことです。したがって、各 $Me テンプレート内には次のものがあります。

<% if HasAccess %>
<% end_if %>

2 つの問題があります。

  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 に答える