I would like to add caching for a block on a per product basis.
I tried just adding:
protected function _construct()
{
//cache for half a day
$this->setCacheLifetime(43200);
}
The problem is a single cache entry is used for every product.
So if I load the first page with products that has specific html in it. Then on all other products the same html is shown.
So it is caching the entire block using a default block tag.
How would I cache the block for the page/url as well as per product?
Update:
$this->getProduct()->getId()
to the getCacheKeyInfo()
function I get the following error:
PHP Fatal error: Call to a member function getId() on null
Update: Add Block Code
class Module_Sticker_Block_Badge extends Mage_Core_Block_Template
{
protected function _construct()
{
//cache the stickers for half a day
$this->setCacheLifetime(43200);
// Add cache tags
// cache tags are used as handles for clearing certain caches
$this->setCacheTag(array(
Mage_Core_Model_Store::CACHE_TAG,
Mage_Cms_Model_Block::CACHE_TAG,
Tengisa_Sticker_Model_Sticker::CACHE_TAG
));
}
// Cache key is unique per bit of HTML
public function getCacheKeyInfo()
{
return array(
Module_Sticker_Model_Sticker::CACHE_TAG,
$this->getNameInLayout(),
Mage::app()->getStore()->getId(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
//Product id
// $this->getParentBlock()->getProduct()->getId()
// Mage::registry('product')->getId()
$this->getProduct()->getId()
);
}
Best Answer
Adding the product ID to
getCacheKeyInfo()
is the right thing to do. But it looks like at least in some cases your block does not have the product available withgetProduct()
. Make sure thatgetProduct()
is implemented and actually returns a product instance.You were talking about category pages, so I assume there are multiple different instances of your block on one page. In this case I don't see sense in using the URL for the cache key.
On product pages you could use
Mage::registry('current_product')
to refer the current product and on category pages, the same with "current_category".I cannot tell, if any of these make sense to you. If you need more concrete help, please update the question with relevant code of your custom block.
Update based on comment
In this case, the block has no access to the product id. Now you have two possible ways to solve it:
use the stickers data for the cache key
additionally pass the product id
and then use it for the cache key
Note that you pass generated HTML (
product->getStickers()->toHtml()
) from outside, so it is generated every time even if the block itself is cached.To optimize this, you should move this HTML generation into the block so that is is only executed if the block is not already cached.
The parent template then should look like this:
The additional data for the cache key:
And the blocks
_beforeToHtml()
method (which is only called if the block was not cached):