Working with View Models
We like Magento view models a lot! In comparison to custom block classes, they are more reusable and composable. You can add an arbitrary number of view models to any template block via layout XML.
But after introducing a bunch of useful view models in Hyvä we got tired of all that seemingly unnecessary XML and thought of a simpler solution:
The View Model Registry
In a Hyvä theme, in every template, a variable $viewModels
is automatically available, introduced by hyva-themes/magento2-theme-module
, similar to the existing $block
and $escaper
variables. You can use it to fetch any view model (i.e. any class that implements ArgumentInterface
).
Example:
/** @var \Hyva\Theme\Model\ViewModelRegistry $viewModels */
$currentProduct = $viewModels->require(\Hyva\Theme\ViewModel\CurrentProduct::class);
Tip
It is no longer needed to declare view models in XML!
You can read more about the usage of ViewModels versus Blocks here: Firegento - Better Blocks: Magento 2 PHP View Models.
View Model Cache Tags
View models are often used to provide data to be rendered in a template.
In case you need the cache tags from some entities to be included in the HTTP response for the FPC cache record, you can implement the Magento\Framework\DataObject\IdentityInterface
and return the required cache tags.
They will be included in the HTTP response X-Magento-Tags
header automatically.
For more information have a look at the in depth documentation.
View Model cache tags in ESI cached blocks
If a block has a ttl="..."
attribute in layout XML, it will be cached by Varnish and included as an ESI section.
If the view model also implements the IdentityInterface
to provide cache tags to the full page cache, this leads to the situation where the cache tags are added to both the full page cache record and also the ESI cache record.
However, the desired behavior is that the cache tags are only added to the ESI cache record.
To allow the view model registry to detect if the view model is rendered in a template that as part of an ESI section, the $block
variable needs to be passed to the $viewModelRegistry->require()
method as a second argument.
/** @var \Hyva\Theme\Model\ViewModelRegistry $viewModels */
$currentProduct = $viewModels->require(\Hyva\Theme\ViewModel\CurrentProduct::class, $block);
Only pass $block
when required
The $block
argument only needs to be specified for view models with cache tags that are used in templates rendered in an ESI section.
In the default Hyvä theme, this is only true for the top menu block templates Magento_Theme/templates/html/header/menu/desktop.phtml
and Magento_Theme/templates/html/header/menu/mobile.phtml
.
Do not all the $block
argument everywhere just in case.