Magento 2 - View models

October 19, 2021

Magento 2: When and how to use view models

Programing is about thinking, not writing Photo by olia danilevich from Pexels

What is a view model

A view model is an abstraction of the view exposing public properties and commands. It allows you 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.

<block name="demoapp.content.viewmodel" template="DemoApp_Catalog::demo.phtml">
        <argument name="view_model" xsi:type="object">DemoApp\Sales\ViewModel\ExampleViewModel</argument>

You can also use this view model on existing blocks used by Magento 2 or by 3rd-party vendors in your modules. All you have to do is to pass view model class as an argument in page layout xml configuration file.

Let's say for example that we want to add our view model to invoice_totals block by referencing block in sales_email_order_invoice_items.xml page layout. Just use <referenceBlock> with name of block and pass argument with namespace of view model class and object as type - be aware that you pass namespace without first slash.

<?xml version="1.0"?>
<page xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd" label="Email Invoice Items List" design_abstraction="custom">
        <referenceBlock name="invoice_totals">
                <argument name="view_model" xsi:type="object">DemoApp\Sales\ViewModel\ExampleViewModel</argument>

The view model class

In your view model class you can have as many methods as you want. The one and only difference is that if you want to use your class as view model you must always implement \Magento\Framework\View\Element\Block\ArgumentInterface interface. Everything else is in your domain - e.g. how much dependencies you will need/add in constructor if any and what methods will you implement.

The most simple example of view model class would be something like this:

namespace DemoApp\Sales\ViewModel;

use \Magento\Framework\View\Element\Block\ArgumentInterface;

class ExampleViewModel implements ArgumentInterface
    public function getSomeDemoText()
      return __('My demo text');

The last step before moving to the template part and finally using your view model function is to compile your DI configuration (it generates DI configuration and all missing classes that can be auto-generated - you'll find them in generated/code folder as interceptor classes)

To compile DI just wrote in your console bin/magento setup:di:compile or if you want short version bin/magento s:d:c command.

When this it's done you can use getSomeDemoText() function in block's template by calling it by viewModel argument name or using getData() function on block - both will work.


/** @var $viewModel \DemoApp\Sales\ViewModel\ExampleViewModel */
$viewModel = $block->getViewModel();
$viewModelText = $block->getData('view_model')

<p><?= $block->escapeHtml($viewModel->getSomeDemoText()); ?></p>
<p><?= $block->escapeHtml($viewModelText->getSomeDemoText()); ?></p>

View models are helpful when you need to customize some templates and add some text, adjust business logic and call function to check something and then display some text paragraph or anything else related to your business requirements and you don't want to override blocks if it's not necessary.

One good example of using view model is if you want to display custom text on invoice for specific customer groups or if customer paid with specific payment method. It's very handy and easy to use view model in that case.

I hope this helped you understand how to add a view model in Magento 2 blocks using arguments and in which case use view models. If you want to get more information, check official docs at magento devdocs.

Join the Newsletter

Subscribe to get our latest content by email.

    We won't send you spam. Unsubscribe at any time.

    Join the Newsletter

    Subscribe to get our latest content by email.
      We respect your privacy. Unsubscribe at any time.