2

1.catalog_product_view.xml inside custom theme Magento_Catalog folder

    <referenceBlock name="product.info.addtocart">
         <arguments>
             <argument name="view_model" xsi:type="object">Tavant\Catalog\ViewModel\OversizeViewModel</argument>
         </arguments>
    </referenceBlock>
  1. Calling in product/view/addtocart.phtml
    /* @var $viewModel Tavant\Catalog\ViewModel\OversizeViewModel */
    
    $viewModel = $block->getViewModel();
    
    echo $viewModel->getTitle();
  1. View Model File
namespace Tavant\Catalog\ViewModel;

class OversizeViewModel implements \Magento\Framework\View\Element\Block\ArgumentInterface
{
    public function __construct()
    {
    }

    public function getTitle()
    {
        return 'Hello World';
    }
}

2 Answers 2

0

There are more blocks using Magento_Catalog::product/view/addtocart.phtml, but you haven't declared view_model so you get this error.

To find which blocks using this phtml file, find "Magento_Catalog::product/view/addtocart.phtml" in vendor/magento directory.

There are 4 blocks in 3 layout files using this phtml: Magento_Catalog/layout/catalog_product_view.xml, Magento_Bundle/layout/catalog_product_view_type_bundle.xml, and Magento_Wishlist/layout/wishlist_index_configure_type_bundle.xml.

Finaly, to use View Model in Magento_Catalog::product/view/addtocart.phtml, you have to declare view_model to 4 blocks:

  • app/theme/<Vendor>/<themeName>/Magento_Catalog/layout/catalog_product_view.xml:
<referenceBlock name="product.info.addtocart">
     <arguments>
         <argument name="view_model" xsi:type="object">Tavant\Catalog\ViewModel\OversizeViewModel</argument>
     </arguments>
</referenceBlock>
<referenceBlock name="product.info.addtocart.additional">
     <arguments>
         <argument name="view_model" xsi:type="object">Tavant\Catalog\ViewModel\OversizeViewModel</argument>
     </arguments>
</referenceBlock>
  • app/theme/<Vendor>/<themeName>/Magento_Bundle/layout/catalog_product_view_type_bundle.xml:
<referenceBlock name="product.info.addtocart.bundle">
     <arguments>
         <argument name="view_model" xsi:type="object">Tavant\Catalog\ViewModel\OversizeViewModel</argument>
     </arguments>
</referenceBlock>
  • app/theme/<Vendor>/<themeName>/Magento_Wishlist/layout/wishlist_index_configure_type_bundle.xml:
<referenceBlock name="product.info.addtocart.bundle">
     <arguments>
         <argument name="view_model" xsi:type="object">Tavant\Catalog\ViewModel\OversizeViewModel</argument>
     </arguments>
</referenceBlock>

Don't forget to clear cache (layout type) after making the changes.

0

It is because you've added the view model in one block but other areas used this template. So Instead of adding the view model in the blocks argument in the layout, we can add the view model to the block in the .php files using plugins as below.

In your case we need to add the before plugin for '\Magento\Catalog\Block\Product\View.php'

Declare the plugin di.xml in the app/code/Tavant/Catalog/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Block\Product\View">
        <plugin name="adding_view_model" type="Tavant\Catalog\Plugin\View" sortOrder="1"/>
    </type>
</config>

The plugin view.php as app/code/Tavant/Catalog/Plugin/View.php

<?php

namespace Tavant\Catalog\Plugin;

use Magento\Catalog\Block\Product\View as Subject;
use Tavant\Catalog\ViewModel\OversizeViewModel;

class View
{
    /**
     * @var OversizeViewModel
     */
    protected $viewModel;

    public function __construct(OversizeViewModel $viewModel)
    {
        $this->viewModel = $viewModel;
    }

    /**
     * @param Subject $subject
     *
     * @return array
     */
    public function beforeToHtml(Subject $subject): array
    {
        $subject->assign('viewModel', $this->viewModel);

        return [];
    }
}

In this way, the view model will be added to this PHP class in the area where it is used in the layout file.

This method is also used to add the view model to the widgets.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.