2

I've been looking around and can't seem to find anything, maybe it's not possible.

For a forum plugin I'm toying with, topics use more data outside of the page in craft's db, so I need a way to bust the cache as craft won't be able to detect a change. So is there a way to 'bust' the Craft Cache possibly with a variable? I'd love to be able to do something like:

{% set param = craft.request.getParam( 'newreply' ) %}

{% cache globally using key craft.request.path until param == '1' %}
    {# generated page content #}
{% endcache %}

This way it'd stay cached until the page was requested with ?newreply=1, effectively busting the cache.

This doesn't seem to be working though. Does anyone have any ideas how this could be accomplished? If not possible with twig, would there be a way to do it in a plugin?

For example, what if I did something like:

{# twig template #}

{{ craft.myplugin.clearcache( craft.request.path ) }}



{# MyPluginVariable.php #}

public function clearcache($pageid)
{

    craft()->templateCache->deleteCacheById($pageid);

    return true;

}

That doesn't seem to do anything though

  • I wonder what happens if you set the until value to a time in the past? Something like now|date_modify("-1 day") – Ben Parizek Mar 25 '15 at 4:35
  • Tried it out, doesn't bust cache :[ – taylor Mar 25 '15 at 6:10
  • What if you append the query string to the key? I.e. {% cache globally using key craft.request.path ~ '?' ~ craft.request.queryString %} – Mats Mikkel Rummelhoff Mar 25 '15 at 8:37
  • That wouldn't get the effect I'm hoping for, as I'd like to flush the cache for the page without the query string. Basically what I want to accomplish is whenever someone writes a new reply to a forum topic, their browser would refresh the page with ?newreply=1, flushing the topic's cache so everyone can see the new response – taylor Mar 25 '15 at 18:59
  • 1
    FWIW, you're original example won't work because until is specifically looking for a date/time. – Brad Bell Mar 25 '15 at 20:39
6

EDIT

Craft 2.4 is now available, adding the deleteCachesByKey method. This means the following would be the best solution to this question:

public function clearcache($key)
{
    craft()->templateCache->deleteCachesByKey($key);
}

ORIGINAL

Your original attempt using a variable method will actually work (as long as the call to the variable method clearcache occurs before the cache tag in your template, of course).

Your problem is that the deleteCacheById() method expects the template cache's database ID, not the cache key.

Unfortunately, TemplateCacheService doesn't actually offer an easy way to delete a cache by its key, so you'll need to get your hands dirty with a custom SQL query:

public function clearcache( $key )
{
    craft()->db->createCommand()->delete( 'templatecaches', 'cacheKey=:key', array( ':key'=> $key ) );
}

Disclaimer: I'd imagine there's a good reason why there's no core deleteCacheByKey method, so it'd be great if somebody with a deeper knowledge of template caches could chime in. Might be there's some ramifications or negative side effects to deleting a cache manually like this.

Sidenote 1: Since the clearcache method shouldn't return any data, consider using Twig's do method to call it:

{% do craft.myplugin.clearcache( craft.request.path ) %}

Sidenote 2: Instead of using a combination of GET variables and plugin variable methods to clear the cache, you might want to consider an implementation where you POST your "replies" form to a controller action method in your plugin. The controller could then be responsible for

  1. Saving the reply (possibly to an external application using cURL?)
  2. Busting the relevant template cache w/ a custom DbCommand
  3. Redirecting back to the referring page

Having a controller (which in turn might call methods on a service to execute on the above points) might, in my opinion, make for a cleaner implementation than the proposed solution (just based on the limited information you've provided, of course – I wouldn't know about the details or inner workings of your application).

| improve this answer | |
  • Thanks, Mats! Your modification to 'clearcache()' worked exactly as is, nice! I moved it all out of twig and instead the clearcache() function is being triggered by the service that handles inserting new replies, I agree that is a much cleaner implementation. For now, I think this is good enough to move on from, but I am curious to learn more about the craft caching and why there isn't core functionality to do this. There probably is a good reason. If anyone also has any thoughts/knowledge on this I'd love to read about it for curiosities sake. – taylor Mar 26 '15 at 3:41
  • Nice fix Mats! I totally agree... deleteCacheByKey should probably be an official thing. Might be worth posting a feature request on feedback.buildwithcraft.com! – Lindsey D Mar 26 '15 at 17:03
  • I concur – and so does apparently Brandon Kelly, as he added a feature request for it a few weeks back :) -> feedback.buildwithcraft.com/forums/285221-feature-requests/… – Mats Mikkel Rummelhoff Mar 26 '15 at 21:39
1

I haven't tested this but I'm pretty sure what you want is:

{% cache globally using key craft.request.path unless param == '1' %}

More information on the unless parameter can be found at http://buildwithcraft.com/docs/templating/cache

| improve this answer | |
  • I've tried this, it does bypass the cache if param == '1', but does not clear the cache, which is what I'm trying to do – taylor Mar 25 '15 at 23:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.