gpt4 book ai didi

php - Magento:如果小部件参数发生变化,则从 block /整页缓存中刷新小部件

转载 作者:行者123 更新时间:2023-12-02 05:43:37 25 4
gpt4 key购买 nike

我们商店的起始页上有一个小部件。

店铺使用FPC和block cache。

如果管理员在后台更改小部件设置,我们如何更新小部件内容?

是否可以在CacheKey中使用Widget的配置数据?

或者我们是否必须将缓存生命周期设置得非常小?

编辑:我自己的答案使用缓存生命周期。只有当小部件实例被编辑时,才从 FPC 中有针对性地清除缓存 block 的方法是什么?

最佳答案

EE 全页缓存和小部件实例缓存

(无重写,无限缓存生命周期)

概览

第一步是创建前端小部件本身,但要提供一些可供完整页面缓存使用的额外信息。
第二步是在整个页面缓存中为小部件处理打洞。
第三步是如果在管理区域中更改了该小部件,则仅自动清除该小部件的小部件缓存。

第一步:创建小部件

首先,为您的模块创建 etc/widget.xml 文件:

<widgets>
<netzarbeiter_test type="netzarbeiter_test/widget_test">
<name>FPC Holepunch Cache Test</name>
<description>Dummy test widget</description>
<parameters>
<!-- This is the important parameter here: -->
<unique_id>
<required>1</required>
</unique_id>
<example_text>
<visible>1</visible>
<label>Example Text Parameter</label>
<type>text</type>
</example_text>
</parameters>
</netzarbeiter_test>
</widgets>

注意参数 <unique_id> .我们不提供输入类型或值,Mage_Widget_Block_Adminhtml_Widget_Options::_addField() 会自动用生成的值填充它方法:

    // Excerpt from Mage_Widget_Block_Adminhtml_Widget_Options::_addField()

if ($values = $this->getWidgetValues()) {
$data['value'] = (isset($values[$fieldName]) ? $values[$fieldName] : '');
}
else {
$data['value'] = $parameter->getValue();
//prepare unique id value
if ($fieldName == 'unique_id' && $data['value'] == '') {
$data['value'] = md5(microtime(1));
}
}

因为有了这个小 gem ,我们不必重写 Mage_Widget_Model_Widget_Instance类以将小部件 ID 注入(inject)到生成的布局 xml 中。

接下来,创建小部件类本身。这只是一个实现 Mage_Widget_Block_Interface 的常规 block 实例接口(interface),除了unique_id用于 cacheKeyInfo方法。

class Netzarbeiter_Test_Block_Widget_Test
extends Mage_Core_Block_Abstract
implements Mage_Widget_Block_Interface
{
public function getCacheKeyInfo()
{
$info = parent::getCacheKeyInfo();
if ($id = $this->getData('unique_id')) {
// Because the array key is a string, it will be added to the FPC placeholder
// parameters. That is how the FPC container can access it (see below).
$info['unique_id'] = (string) $id;
}
return $info;
}

protected function _toHtml()
{
// The FPC was completely cleared (or not created yet),
// recreate the widget parameter cache
if (! $this->getFullPageCacheEnvironment() && $this->getUniqueId()) {
$id = Netzarbeiter_Test_Model_Fpc_Container_Widget_Test::CACHE_PREFIX . $this->getUniqueId() . '_params';
Enterprise_PageCache_Model_Cache::getCacheInstance()->save(serialize($this->getData()), $id);
}
// Just some dummy output to display the text parameter and the render time
$time = now();
$textParam = $this->escapeHtml($this->getExampleText());
return <<<EOF
<p><b>Render Time:</b> {$time}<br/>
<b>Example Text:</b> {$textParam}<br/></p>
EOF;
}
}

当我们现在通过管理界面添加一个小部件实例时,unique_id widget.xml 中指定的参数将被添加到布局 xml(为便于阅读而添加的格式:

SELECT layout_update_id, handle, xml FROM core_layout_update;
+------------------+--------------------------+----------------------------------------------------------------------------------------------------+
| layout_update_id | handle | xml |
+------------------+--------------------------+----------------------------------------------------------------------------------------------------+
| 17 | catalog_category_layered | <reference name="left">
| | | <block type="netzarbeiter_test/widget_test" name="2a3b55e13549e176709fc6c67a4a7bd8">
| | | <action method="setData">
| | | <name>unique_id</name>
| | | <value>7fa2574145ef204fb6d179cfc604ac76</value>
| | | </action>
| | | <action method="setData">
| | | <name>example_text</name>
| | | <value>This is a String!</value>
| | | </action>
| | | </block>
| | | </reference>
+------------------+--------------------------+----------------------------------------------------------------------------------------------------+

这意味着,每当通过布局 xml 渲染创建 block 实例时,unique_id参数将在 block 对象上已知。

第二步:全页缓存打洞

添加 etc/cache.xml 文件:

<config>
<placeholders>
<cms_block_widget>
<block>netzarbeiter_test/widget_test</block>
<placeholder>WIDGET_FPC_TEST</placeholder>
<container>Netzarbeiter_Test_Model_Fpc_Container_Widget_Test</container>
</cms_block_widget>
</placeholders>
</config>

接下来,创建容器类:

class Netzarbeiter_Test_Model_Fpc_Container_Widget_Test
extends Enterprise_PageCache_Model_Container_Abstract
{
const CACHE_PREFIX = 'TEST_WIDGET_';

protected function _getCacheId()
{
return self::CACHE_PREFIX . $this->_placeholder->getAttribute('unique_id');
}

protected function _renderBlock()
{
$block = $this->_getPlaceHolderBlock();
// Set any parameters from the placeholder on the block as needed.
// See observer below where the current parameters are cached.
$id = $this->_getCacheId() . '_params';
if ($parameters = Enterprise_PageCache_Model_Cache::getCacheInstance()->load($id)) {
$block->addData(unserialize($parameters));
// Set environment information on block (used in _toHtml,
// the params cache is recreated when not set)
$block->setFullPageCacheEnvironment(true);
}
Mage::dispatchEvent('render_block', array('block' => $block, 'placeholder' => $this->_placeholder));
return $block->toHtml();
}
}

这就是使我们的小部件成为完全缓存页面中的动态 block 所需的全部。但到目前为止,小部件 block 被无限期缓存。我们仍然需要处理缓存刷新。

第三步:小部件保存时缓存刷新

为自动 *_save_commit_after 使用事件观察器所有 Magento 模型都提供特定于小部件实例的事件。每次在管理界面中保存小部件实例时都会触发它。

<adminhtml>
<events>
<widget_widget_instance_save_commit_after>
<observers>
<netzarbeiter_test>
<model>netzarbeiter_test/observer</model>
<method>widgetWidgetInstanceSaveCommitAfter</method>
</netzarbeiter_test>
</observers>
</widget_widget_instance_save_commit_after>
</events>
</adminhtml>

最后一 block 拼图是观察者方法:

public function widgetWidgetInstanceSaveCommitAfter(Varien_Event_Observer $observer)
{
/** @var $widget Mage_Widget_Model_Widget_Instance */
$widget = $observer->getEvent()->getObject();
$parameters = $widget->getWidgetParameters();
$uniqueId = isset($parameters['unique_id']) ? $parameters['unique_id'] : '';
if (strlen($uniqueId)) {
$id = Netzarbeiter_Test_Model_Fpc_Container_Widget_Test::CACHE_PREFIX . $uniqueId;
Enterprise_PageCache_Model_Cache::getCacheInstance()->remove($id);
$id = Netzarbeiter_Test_Model_Fpc_Container_Widget_Test::CACHE_PREFIX . $uniqueId . '_params';
Enterprise_PageCache_Model_Cache::getCacheInstance()->save(serialize($parameters), $id);
}
}

总结

现在前端的实例会在每次保存时自动更新,即使有激活的全页缓存。在所有其他时间,将从缓存中获取动态 block 。

编辑:将缓存的小部件参数示例添加到代码中,因为正如 Alex 在下面的评论中指出的那样,只要 FPC 条目存在,占位符参数就不会刷新。
使用缓存将widget参数传递给block,避免了在block动态渲染时重写widget实例模型和加载widget实例。

关于php - Magento:如果小部件参数发生变化,则从 block /整页缓存中刷新小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11436380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com