EE フル ページ キャッシュとウィジェット インスタンスのキャッシュ
(書き換えなし、無制限のキャッシュ寿命)
概要
最初のステップは、フロントエンド ウィジェット自体を作成することですが、フル ページ キャッシュが使用できる追加情報を提供します。
2 番目のステップは、ウィジェットのフル ページ キャッシュでホール パンチングを処理することです。
3 番目のステップは、このウィジェットが管理領域で変更された場合にのみ、ウィジェット キャッシュを自動的に消去することです。
ステップ 1: ウィジェットを作成する
まず、モジュールの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));
}
}
この小さな宝石のおかげで、生成されたレイアウト xml にウィジェット ID を挿入するためにクラスを書き直す必要はありません。Mage_Widget_Model_Widget_Instance
次に、ウィジェット クラス自体を作成します。メソッドで が使用されてMage_Widget_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;
}
}
管理インターフェイスからウィジェット インスタンスを追加すると、 widget.xmlunique_id
で指定されたパラメータがレイアウト 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 レンダリングによって作成されるときはいつでも、unique_id
ブロック オブジェクトでパラメータが認識されることを意味します。
ステップ 2: フルページ キャッシュ ホール パンチング
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();
}
}
完全にキャッシュされたページ内でウィジェットを動的ブロックにするために必要な作業はこれだけです。しかし、これまでのところ、ウィジェット ブロックは無期限にキャッシュされています。キャッシュの更新を処理する必要があります。
ステップ 3: ウィジェット保存時のキャッシュ更新
*_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>
パズルの最後のピースはオブザーバー メソッドです。
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);
}
}
概要
これで、フロントエンドのインスタンスは、フル ページ キャッシュがアクティブ化されていても、保存されるたびに自動的に更新されます。それ以外の場合は常に、動的ブロックがキャッシュからフェッチされます。
編集: キャッシュされたウィジェット パラメーターの例をコードに追加しました。これは、以下のコメントで Alex が指摘したように、FPC エントリが存在する限りプレースホルダー引数が更新されないためです。
キャッシュを使用してウィジェット パラメータをブロックに渡すと、ウィジェット インスタンス モデルを書き換えたり、ブロックが動的にレンダリングされるときにウィジェット インスタンスをロードしたりすることを回避できます。