Magento将当前产品ID传递给模块

时间:2011-11-17 20:42:59

标签: caching magento

我有一个自定义模块,可以在我的产品页面上显示数据。我的模块需要获取当前的产品ID。我尝试使用:

Mage::registry('current_product');

这适用于第一次加载,但是当我刷新时,current_product不再具有完整页面缓存的数据。

有什么想法吗?

2 个答案:

答案 0 :(得分:13)

当整页缓存处理请求时,不调度目录产品操作控制器(这样可以保持快速)。 因此,永远不会设置注册表变量。 我假设您在完全缓存的页面上动态生成块。 我的建议是尽量避免昂贵的负载,因为这会破坏整页缓存的速度提升。你真的想要尽可能地缓存块,即使它是每个客户和每个产品的单独缓存条目。

那就是说,这是怎么做的:

在容器中,实现_getIdentifier()方法:

protected function _getIdentifier()
{
    return $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
}

同时展开_getCacheId()方法以包含方法_getIdentifier()的返回值和新的占位符属性:product_id

protected function _getCacheId()
{
    return 'HOMEPAGE_PRODUCTS' . md5($this->_placeholder->getAttribute('cache_id') . ',' . $this->_placeholder->getAttribute('product_id')) . '_' . $this->_getIdentifier();
}

接下来,在块类中,扩展方法getCacheKeyInfo()。具有字符串索引的cache_key_info数组中的所有条目都在占位符上设置为属性。这就是我们如何将产品ID传递给占位符。

public function getCacheKeyInfo()
{
    $info = parent::getCacheKeyInfo();
    if (Mage::registry('current_product'))
    {
        $info['product_id'] = Mage::registry('current_product')->getId();
    }
    return $info;
}

然后通过而不是启用方法_saveCache(),将其覆盖在容器类中并返回false。 所以现在,因为容器从_getCacheId()返回一个有效的id,并且_saveCache()是从父类继承的,所以该块可以被缓存,并以{{1的有效方式应用于内容}}

您可以通过让容器从Enterprise_PageCache_Model_Container_Abstract::applyWithoutApp()而不是Enterprise_PageCache_Model_Container_Customer扩展来设置缓存条目的生命周期。

如果您仍然需要将product_id传递给块(即使它现在已缓存),您可以使用容器的Enterprise_PageCache_Model_Container_Abstract方法执行此操作:

_renderBlock()

答案 1 :(得分:0)

你应该在你的模块的控制器中有一些启动当前产品注册的东西。您需要在用户访问的页面之间发布您的产品ID(推荐)或将其保存在会话中。以下是您可以在控制器中执行的操作的示例:

protected function _initAction(){

    if(! Mage::registry('current_product')){
        Mage::register('current_product', Mage::getModel('catalog/product'));
    }

    $id = $this->getRequest()->getParam('id');
    if (!is_null($id)) {
        $model = Mage::registry('current_product')->load($id);

        if (! $model->getId()) {
            $this->_getSession()->addError(Mage::helper('catalog')->__('This product item no longer exists'));
            $this->_redirect('*/*/');
            return;
        }
    }

    return $this;
}

public function indexAction()
{
  $this->_initAction();
  // your code below
}