View Model Cache Tags
This document assumes you are familiar with Magento Block HTML & Full Page Caching.
Hyvä themes extensively uses View Models to provide the data to templates for rendering.
The Hyvä Theme module assigns a View Model registry to all templates, to allow access to required view models.
/** @varHyvaThemeModelViewModelRegistry $viewModels */
$productPriceViewModel = $viewModels->require(HyvaThemeViewModelProductPrice::class);
Because in Hyvä all View Models are created through the central view model registry, it is possible to solve this problem.
In Hyvä Themes, View Models can implement the same IdentityInterface
as Blocks to specify cache tags.
class CurrentProduct implements
ArgumentInterface,
\Magento\Framework\DataObject\IdentityInterface
{
// ....
public function getIdentities()
{
return $this->currentProduct instanceof IdentityInterface
? $this->currentProduct->getIdentities()
: [];
}
}
Any cache tags returned by a view model’s getIdentities()
method will automatically be added to the page response, both for regular page requests and for ESI requests.
Implementation Details
Tip
The following content is internal documentation to help future Hyvä development.
It is not required reading to use Hyvä.
Adding View Model Cache Tags to the Response
The ViewModelRegistry
calls Hyva\Theme\Model\ViewModelCacheTags::collectFrom($viewModel)
each time a view model is required by a template.
The ViewModelCacheTags
instance stores a reference to all view models implementing the IdentityInterface
.
To retrieve the collected cache tags, the class provides a method get()
.
Note
The collected view model’s getIdentities()
methods are called as lazily as possible in case a view model aggregates them over time during rendering.
This most notably is the case for the Navigation view model used by the top menu template.
The following process handles the correct cleaning of cache records by tags in all cases:
- Only FPC enabled
- Only Block HTML cache enabled
- Both FPC and Block HTML cache enabled
The view model cache tags are required for building the X-Magento-Tags
response headers in two scenarios:
- In response to page requests
- In response to ESI requests
Page Responses
For page responses, the cache tags are retrieved by a block Hyva\Theme\Block\ViewModelCacheTagsBlock
, which is injected into every page in the before.body.end
container using the hyva_default
layout handle.
The block renders nothing, but it implements the IdentityInterface
to return the combined cache tags collected by the ViewModelCacheTags
instance.
The block’s getIdentity
method is called through the regular Magento process by which block cache tags are added to page responses
Note
In developer mode the block renders a HTML comment containing all the view model cache tags for debugging purposes.
ESI Responses
For ESI requests we have to distinguish if the requested content is also stored in the HTML Block cache or not.
If the content is not stored in the Block HTML cache in addition to the ESI cache, then the cache tags are added to the response just like for regular page responses as described above.
However, if the content is also stored in the Block HTML cache, the content will be returned from the HTML Block cache directly, without the view models being instantiated.
Because of this, no cache tags will be associated with the response to the ESI request. This issue also occurs in native Magento and is most noticeable in case of the top menu block.
Hyvä solves this issue with a plugin on the Layout objects getOutput
method.
It retrieves all blocks, and saves the cache tags for all blocks that are double cached in ESI and the Block HTML cache in a second Block HTML cache record.
When an ESI response is read from the Block HTML cache, the Magento\PageCache\Controller\Block\Esi
plugin Hyva\Theme\Plugin\PageCache\AddViewModelCacheTagesToEsiResponse
reads all the cache tags of the double cached blocks, and adds them to the response X-Magento-Tags
header.