Block cache and URL parameters?

Permalink
Hello,

I have a problem with block-caching and can't find a solution:

On my pages a have a special navigation block. In this block caching is enabled. The output of this block depends on a parameter in the URL. But it seems, that the caching algorithm ignores the url paramters and so my block has always the same output. I just can't find a way how to solve that.

So my navigation block should have different output when i visit the pages
http://testsite/testpage
and
http://testsite/testpage?param=xxx...

Can anybody tell me how to do that?

Thanks a lot
Harald

HarryVienna
 
jordanlev replied on at Permalink Reply
jordanlev
You'll have to disable block caching for the block, which you can do by putting the following code in your block controller class:
protected $btCacheBlockRecord = false;
protected $btCacheBlockOutput = false;
protected $btCacheBlockOutputOnPost = false;
protected $btCacheBlockOutputForRegisteredUsers = false;


(Or, if you already have code similar to that in your block controller, change the values from "true" to "false" where applicable).
HarryVienna replied on at Permalink Reply
HarryVienna
I know that I can disable the cache. The problem is, that the code in this block is very complex and needs some seconds to finish. So I really need caching here.

If I understand right, C5 does not care about URL parameters when caching blocks? Sounds a little bit strange for me. Why not introduce a class variable where you can store additional values for the cache key?

So it seems that I have to do it myself with the Cache class. Not really elegant but it should work... :-)

Cheers
Harald
jordanlev replied on at Permalink Reply
jordanlev
I don't believe C5 looks to url parameters for caching -- I think it is only concerned with the page that's being displayed. My guess is that there's simply too many possibilities for what should and shouldn't be cached based on url parameters so it's best to err on the side of caution (for example, there may be url parameters that don't even have anything to do with blocks on the page, e.g. tracking codes from inbound links or email newsletter clicks, etc.).

So... I think you'll need to implement your own form of caching. Will require a bit of work but nothing too complicated -- just save your calculated data to a table or file somewhere with a timestamp, and have the block controller code check for how long ago the saved timestamp is and decide if you want to re-calculate or not based on that. (That's of course just a very general approach -- but there's probably some details specific to your situation that will effect how you implement the caching).

Good luck,
Jordan
HarryVienna replied on at Permalink Reply
HarryVienna
Thanks Jordon for your reply!

Now i just use Cache::set and Cache::get to store my values. Works fine, the only disadvantage is, that the script does not know when content has changed and so the cache should be invalidated...

If I could have a wish to the C5 team, it would be an additional parameter for the BlockController like

protected $btCacheBlockCacheKey = array("param1","param2");

So that these URL parameters are added to the cache key...

:-)

Cheers,
Harald
jordanlev replied on at Permalink Reply
jordanlev
Perhaps you can combine two pieces of info into the one cache key, for example "mykey-123" or "mykey-456" (the 123 or 456 would be the url parameter)? So C5 just thinks you have a lot of different cache values, but your code would know to parse the two pieces of info in that key properly and use only what's needed.
ScottC replied on at Permalink Reply
ScottC
Well you would need to basically re-implement the way the block view caching works, using the output buffering functions.

This code is off of the top of my head, it is meant for demonstration only
So you would do something like:

ob_start(); //at the top of your block view
//other stuff with your template
//grab your $getVar1 and $getVar2 from $_GET or $_REQUEST
$view = ob_get_flush();

Cache::set('CustomHandle',$getVar1.':'.$getVar2.':'.$bID,$view);

$view = Cache::get('CustomHandle',$getVar1.':'.$getVar2.':'.$bID);

if($view){
print $view;
}else{
//do that complex stuff and set it to cache as above;
}

I typed all of this off of the top of my head. Please read up here on the different functions you could use:

http://www.php.net/manual/en/function.ob-get-flush.php...

That is the general idea to do this sort of thing.
HarryVienna replied on at Permalink Reply
HarryVienna
Thanks a lot for your replys! My solution for the moment is a little bit simpler. I don't cache the whole view but only the data array with the values in it.

I switched on the APC cache and page caching and this works quite well now. Hopefully I can launch my website in a week.. :-)

Cheers
Harald
clocktower replied on at Permalink Reply
clocktower
Jordan, perhaps you can shed some light as I am finding that even updating the controller for custom block modeled after the slideshow block does not prevent caching.

Could this be in the way that we are pulling images into the block view?

Within the view we are using the image helper and getThumbnail() functions in case we want to set a height and width as well as cropping. We have found that this generates an image that is around double the image size of the uploaded image, and the quality setting does not have much impact.

$image = $ih->getThumbnail($f, $imageWidth, $imageHeight, array('crop' => true, 'quality'=>10));