Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Customising the CMS

Run Cache Flush Command (for Varnish) on Publish


Go to End
Reply

9 Posts   882 Views

Avatar
Bam

12 September 2013 at 3:19pm Community Member, 16 Posts

Hi All

I am looking at setting up Varnish with Nginx for Silverstripe. Everything is working well, but I need a way to invalidate pages in the cache when they are updated in the cms. Is there a way I can trigger a local command or a url load when a page is published?

Cheers
Sam

Avatar
simon_w

12 September 2013 at 5:10pm Forum Moderator, 474 Posts

You can use an onAfterWrite() hook on your Page class.

Avatar
Bam

14 September 2013 at 5:10pm Community Member, 16 Posts

Thanks Simon

Will give it a go.

Avatar
Bam

16 September 2013 at 1:18pm Community Member, 16 Posts

Thanks Simon

That worked great!

public function onAfterWrite() {
system('varnishadm -T :6082 "ban.url /"');
return true;
}

Clears the entire cache. Is it possible to replace the / with the current page? So it only clears it for that url? I tried:

public function onAfterWrite() {
system('varnishadm -T :6082 "ban.url $this->URLSegment"');
return true;
}

But that passed through ->URLSegment to the command line rather than the segment.

Thanks
Sam

Avatar
simon_w

16 September 2013 at 1:21pm (Last edited: 16 September 2013 1:22pm), Forum Moderator, 474 Posts

Try:

$cmd = escapeshellarg('ban.url ' . $this->Link());
system('varnishadm -T :6082 ' . $cmd);

[url=http://php.net/escapeshellarg]escapeshellarg()[/url] adds the quotes around the string so you don't need to.

Avatar
Bam

16 September 2013 at 1:37pm Community Member, 16 Posts

Bloody legend, thanks Simon!

Avatar
Bam

16 September 2013 at 1:47pm Community Member, 16 Posts

One last question. This works, but for it to work properly under all circumstances I will need to flush the parents as well, so changes to page titles and the like will filter upwards to the parents.

If $this->Link gives you the whole url. Is there one that will just give you the top level parent? I.e. get /staff/ instead of /staff/fred/

Avatar
simon_w

16 September 2013 at 1:54pm Forum Moderator, 474 Posts

You'd want to call ->Link() on the topmost page, which you can get with something like:

if($this->ParentID) {
$top = $this->getAncestors()->Last();
} else {
$top = $this;
}

Go to Top