Skip to content

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);
Magento does not provide an API for View Models to add cache tags to responses.

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.