Partial Caching $CacheCondition

I’m starting to implement Partial Caching in my project and I am not sure I understand how to select appropriate logic for the $CacheCondition.

From the Docs:

Although $CacheCondition is optional, it is highly recommended. For example, if you use $DataObject->ID as your $CacheKey , you may use $DataObject->ID > 0 as the condition.

So what $CacheConditon, if any, should be applied to the following example from the docs?

<% cached
     'navigation',
     $List('SilverStripe\CMS\Model\SiteTree').max('LastEdited'),
     $List('SilverStripe\CMS\Model\SiteTree').count()
%>

If it would be none, please could someone explain why?

Many thanks!

I don’t think you really need to use $cacheCondition here unless there is any conditions on whether a navigation item/page is visible or not based on the current user session/state, in most cases that is all i ever really use the $cacheCondition for.

The cache condition basically says “only cache this portion of the template if some condition is true”. You might use it for example to avoid caching if a user is logged in if there are some user-specific portions in your template.

In the example of navigation, it is unlikely that you would want to not cache the navigation ever. You probably always want that cached - and if there’s some small portion which changes based on a condition you’d be better off using <% uncached %> for it.

But you might have a welcome message block which normally just says “Welcome to the site here is some information yaddayadda” but if someone’s logged in it might say “Welcome John, here is some specific information that is just for you”. In that case you might want to have a cache condition on whether someone is logged in. That way it would use the cached copy for all anonymous users, but anyone logged in would get their customised information.

Thank you for they replies, very helpful.

I have a few more general questions about Partial Caching that hopefully you can help with:

  • The 10 minute cache lifetime default seems short. Wouldn’t cache invalidation be better handled by an appropriate $cacheKey?
  • The docs state you cannot nest cache blocks in IF statements, but nested cache blocks seem to work as expected. Is there any practical reason to avoid nesting?
  • Where are the partial cache blocks stored?

Many thanks for reading and sorry if these are silly questions!

The 10 minute cache lifetime default seems short.

The 10 minute lifetime is to avoid issues where the cache key isn’t perfect - which is extremely common. Basically it’s better to invalidate relatively frequently and avoid having your content creators complaining all the time. By and large caching in the web is to avoid issues with load anyway.
But as the docs say, if your cache key is good enough and you’re confident you won’t have issues, you can increase that timeout.

Is there any practical reason to avoid nesting?

My guess is that this was a technical limitation, due to the complexity of avoiding caching something for passing the condition when the condition fails, or some such. If it works now, then perhaps someone overcame that challenge and the docs just didn’t get updated to reflect it. Or perhaps it’s not actually caching anything and that’s why it seems to be working ;p

Where are the partial cache blocks stored?

Inside the silverstripe-cache* directory. If you created a silverstripe-cache directory in your project root then it’ll be there, otherwise it’ll be somewhere in your system’s tmp directory.

Thank you for the detailed reply @GuySartorelli, very much appreciated :slight_smile:

Given the statement in bold, in the following paragraph from the $CacheCondition section in the docs:

If the value is false , the block skips $CacheKey evaluation completely, does not lookup the data in the cache storage, neither preserve any data in the storage. The template within the block keeps working as is, same as it would do without <% cached %> block surrounding it.

Should I expect a cache block to be purged if $CacheConditon == false?

Partial cache is never “purged” - there’s no mechanism that I’m aware of in core to actually delete the cache files (though there is at least one module out there which does cleanup of this and other things). Instead, if the cache condition is false it simply doesn’t use the cached copy for that block of the template. Similarly if the cache key doesn’t match an existing cache, or the cache is too old, a new cache file is generated for the block.

Where it says it doesn’t “preserve any data in the storage” basically that’s just an unnecessarily obtuse way of saying “If the cache condition is false, it doesn’t use the cache at all for that block - it neither reads nor writes to the cache”

Perfect, thank you for clarifying :+1:

1 Like