Edit in GitHubLog an issue
Thanks to Space 48 for contributing this topic!

View models

A view model is an abstraction of the view exposing public properties and commands. It allows developers to offload features and business logic from block classes into separate classes that are easier to maintain, test, and reuse.

When to use view models#

Use this approach anytime you need to inject functionality into template files and your code does not need to be backwards compatible with Magento.

How to write view models#

View models can be used by passing the view model class as an argument to a template's block in the page layout configuration file. In the following example snippet, MyNewViewModel is the view model class of the ExampleCorp_Catalog module passed as an argument to a block.

Copied to your clipboard
1<block name="examplecorp.new.viewmodel" template="ExampleCorp_Catalog::example.phtml">
2 <arguments>
3 <argument name="view_model" xsi:type="object">ExampleCorp\Catalog\ViewModel\MyNewViewModel</argument>
4 </arguments>
5</block>

In the following example, the same view model is used with an existing block in Magento/Checkout/view/frontend/layout/checkout_cart_item_renderers.xml.

Copied to your clipboard
1<referenceBlock name="checkout.cart.item.renderers.default">
2 <arguments>
3 <argument name="view_model" xsi:type="object">ExampleCorp\Catalog\ViewModel\MyNewViewModel</argument>
4 </arguments>
5</referenceBlock>

The view model class must always implement the interface \Magento\Framework\View\Element\Block\ArgumentInterface. For example:

Copied to your clipboard
1namespace ExampleCorp\Catalog\ViewModel;
2
3class MyNewViewModel implements \Magento\Framework\View\Element\Block\ArgumentInterface
4{
5 public function getTitle()
6 {
7 return 'Hello World';
8 }
9}

You can access the public methods for the view model class in the template:

Copied to your clipboard
1<?php
2
3/** @var $viewModel \ExampleCorp\Catalog\ViewModel\MyNewViewModel */
4
5$viewModel = $block->getViewModel();
6
7?>
8<h1><?= $block->escapeHtml($viewModel->getTitle()); ?></h1>

Examples#

  • Theme. This view_model is injected into a template to return the target store redirect url.

The following is an example of view model usage within the Magento/Catalog/view/frontend/layout/catalog_product_view.xml layout file.

The view model class is passed as an argument to the product.info.upsell block in the layout configuration file:

Copied to your clipboard
1<block class="Magento\Catalog\Block\Product\ProductList\Upsell" name="product.info.upsell" template="Magento_Catalog::product/list/items.phtml">
2 <arguments>
3 <argument name="type" xsi:type="string">upsell</argument>
4 <argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Product\Listing\PreparePostData</argument>
5 </arguments>
6</block>

The following is an example of the view model class Magento/Catalog/ViewModel/Product/Listing/PreparePostData.php implementation in the catalog module.

The class must implement the \Magento\Framework\View\Element\Block\ArgumentInterface interface class.

Copied to your clipboard
1namespace Magento\Catalog\ViewModel\Product\Listing;
2
3use Magento\Framework\View\Element\Block\ArgumentInterface;
4use Magento\Framework\App\ActionInterface;
5use Magento\Framework\Url\Helper\Data as UrlHelper;
6
7/**
8 * Check is available add to compare.
9 */
10class PreparePostData implements ArgumentInterface
11{
12 /**
13 * @var UrlHelper
14 */
15 private $urlHelper;
16
17 /**
18 * @param UrlHelper $urlHelper
19 */
20 public function __construct(UrlHelper $urlHelper)
21 {
22 $this->urlHelper = $urlHelper;
23 }
24
25 /**
26 * Wrapper for the PostHelper::getPostData()
27 *
28 * @param string $url
29 * @param array $data
30 * @return array
31 */
32 public function getPostData(string $url, array $data = []):array
33 {
34 if (!isset($data[ActionInterface::PARAM_NAME_URL_ENCODED])) {
35 $data[ActionInterface::PARAM_NAME_URL_ENCODED] = $this->urlHelper->getEncodedUrl();
36 }
37 return ['action' => $url, 'data' => $data];
38 }
39}

The following is an example of the view model initialization in the app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml template.

Copied to your clipboard
1/** @var $viewModel /Magento/Catalog/ViewModel/Product/Listing/PreparePostData */
2$viewModel = $block->getViewModel();
3$postArray = $viewModel->getPostData(
4 $block->escapeUrl($block->getAddToCartUrl($_item)),
5 ['product' => $_item->getEntityId()]
6);
Was this helpful?
  • Privacy
  • Terms of Use
  • Do not sell my personal information
  • AdChoices
Copyright © 2022 Adobe. All rights reserved.