Jump to:

22977 Posts in 11806 Topics by 2826 members

General Questions

SilverStripe Forums » General Questions » Partial Caching - Understanding the Concepts

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1 2
Go to End
Author Topic: 4057 Views
  • edk
    Avatar
    Community Member
    39 Posts

    Partial Caching - Understanding the Concepts Link to this post

    This page [url=http://doc.silverstripe.org/partial-caching?s[]=partial&s[]=caching]http://doc.silverstripe.org/partial-caching?s[]=partial&s[]=caching does a great job at trying to explain this concept. I am looking for some more concrete example, especially as it woudl relate to a method called in a Page Class and used in a control block.

    I would appreciate anyone taking a stab a dumbing this down for me, on more level.

    Some Sample Code:
    Let's say we have a method in the Page Class that is getting the latest blog posts...

    function LatestBlogPosts($num=5) {
          $blogs = DataObject::get_one("BlogHolder");
          return ($blogs) ? DataObject::get("BlogEntry", "ParentID = $blogs->ID", "Date DESC", "", $num) : false;
       }

    and then without any caching I would call this in a page template like so...

    <% if LatestBlogPosts %>
        <ul>
        <% control LatestBlogPosts %>
        <li><a href="$Link" title="Read more on &quot;{$Title}&quot;">$Title</a></li>
        <% end_control %>
        </ul>
       <% end_if %>

    Can someone tell me what the cache call would be for this to check if there was an updated post and then get the new result if there was.

    is this even close?

    <% cached 'LatestBlogPosts', Aggregate(BlogEntry).Max(LastEdited) %>

    Thanks in advance. I think this feature looks awesome. Another hidden gem in SIlverstripe.

    - Ed

  • Willr
    Avatar
    Forum Moderator
    5462 Posts

    Re: Partial Caching - Understanding the Concepts Link to this post

    Yes, that is in fact one of the examples on the page

    <% cached 'navigation', Aggregate(Page).Max(LastEdited) %>

    Its in the format

    <% cached 'uniquename', function %>

    Where unique name is a reference for that cache block and function to return a string to build the unique cache store. For example latest blog...

    <% cached 'blogposts', Aggregate(BlogEntry).Max(LastEdited) %>

    <% end_cached %>

    If you edited the blog entry at 9am your cache key would be like "blogposts-0900". If you visited that page again and you hadn't edited the page and came back to the site at 2pm then the cache key still would be blogposts-0900, that key exists in the store so it would pull from the cached version. So the function (or functions) are used to decide whether to update that block. You can pass an unlimited amount of functions to a cached control.

    Your probably asking yourself "Well hang on then it still needs to do a database query for the last edited date, so the 'cache' still hits that database!!" You are correct but doing a DB::query() for a single value is a heck of a lot faster than a DataObject::get().

    Documentation is really quite good on this http://doc.silverstripe.org/partial-caching

    * note my date example is simplified.

  • edk
    Avatar
    Community Member
    39 Posts

    Re: Partial Caching - Understanding the Concepts Link to this post

    Thanks for the extended explanation. The 'uniquename' declaration was what a little ambiguous in the guide in the site. I would even suggest added this part of the explanation in the guide. Your simple explanation here, added that missing part that I was looking for to understand completely how the partial caching works.

    Thanks again Willr.

  • edk
    Avatar
    Community Member
    39 Posts

    Re: Partial Caching - Understanding the Concepts Link to this post

    Okay, so I am struggling with how to achieve the following...I have a control Structure for a navigation item that uses ChildrenOf...

    <% if ChildrenOf(portfolio) %>
    <ul>
    <% control ChildrenOf(portfolio) %>
        <li><a class="$LinkingMode" href="$Link" title="Go to the {$Title} page">$MenuTitle</a></li>
       <% end_control %>
    </ul>
    <% end_if %>

    I have tried to use the ChildrenOf(portfolio) in the Aggregrate call but am getting errors

    <% cached 'navigation_portfolio', Aggregate(ChildrenOf(portfolio)).Max(LastEdited) %>

    I am probably going about this the wrong way. Any help would be appreciated.

    - Ed

  • Willr
    Avatar
    Forum Moderator
    5462 Posts

    Re: Partial Caching - Understanding the Concepts Link to this post

    AFAIK Aggregate is a specific ClassName (eg SiteTree) not a function.

  • Dramew
    Avatar
    Community Member
    9 Posts

    Re: Partial Caching - Understanding the Concepts Link to this post

    I really do not understand one thing in partial caching. To what is "cached part of website" connected to? It is said in documentation that each cache block has a unique cache key. So, for example (taken from documentation):

    From a block that updates every time the Page subclass it's the template for updates
    <% cached 'database', LastEdited %>


    Let's assume I put that into Page.ss layout template. I have several pages on my website, who use this layout template (Page.ss).
    What will be cached? Every page which uses Page.ss will have the same cached content (for example, if wrap the whole template Page.ss with the "cached")? Or it will take LastEdited for every page I open in my browser and content will be different for each page?

    I hope that I explained my problem clearly. And thanks in advance!

  • Willr
    Avatar
    Forum Moderator
    5462 Posts

    Re: Partial Caching - Understanding the Concepts Link to this post

    Let's assume I put that into Page.ss layout template. I have several pages on my website, who use this layout template (Page.ss).
    What will be cached? Every page which uses Page.ss will have the same cached content (for example, if wrap the whole template Page.ss with the "cached")? Or it will take LastEdited for every page I open in my browser and content will be different for each page

    It will use a cache key of the last edited date for that page and if you put that on Page.ss then it will be on a per page basis. So the Last Edited date of each page. I'm 90% sure this works on a per page. Even the Aggregate functions may cache on a per page url basis but I will need to check.

  • Tonyair
    Avatar
    Community Member
    81 Posts

    Re: Partial Caching - Understanding the Concepts Link to this post

    Here's example with paginator:

    class StaffPage_Controller extends Page_Controller {
       private $start;
       public function init() {
          parent::init();
          if(!isset($_GET['start']) || !is_numeric($_GET['start']) || (int)$_GET['start'] < 1) $_GET['start'] = 0;
          $this->start = (int)$_GET['start'];
       }

       public function StaffItems() {
          $doSet = DataObject::get(
             $callerClass = "StaffItem",
             $filter = "`StaffPageID` = '".$this->ID."'",
             $sort = "SortOrder",
             $join = "",
             $limit = "{$this->start},10"
          );
          return $doSet ? $doSet : false;
       }
       
       public function CacheKey() {
        return implode('_', array(
        'StaffItems',
       $this->ID,
        $this->RelationshipAggregate('StaffItems')->Max('LastEdited'),
             $this->start
       ));
       }
    }

    StaffPage.ss
    <% cached CacheKey %>

    And the question: if i add <% cached LastEdited %> $Layout <% end_cached %> to Page.ss why StaffPage isn't update when i change StaffItem?

    4057 Views
Page: 1 2
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.