0

I'm trying to create a custom product list taking the related product list as reference.

The related list is defined in the catalog_product_view.xml:

<block class="Magento\Catalog\Block\Product\ProductList\Related" 
       name="catalog.product.related" 
       template="Magento_Catalog::product/list/items.phtml">
 <arguments>
  <argument name="type" xsi:type="string">related</argument>
  <argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Product\Listing\PreparePostData</argument>
 </arguments>
 <block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="related.product.addto" as="addto">
  <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
         name="related.product.addto.compare" as="compare"
         template="Magento_Catalog::product/list/addto/compare.phtml"/>
  </block>
 </block>

I was able to re-create this structure by simply copying the same xml and changing only the name of the block and of the phtml template in some existing container:

<referenceContainer name="name.of.container">
<block class="Vendor\Module\Block\Product\ProductList\CustomList" 
      name="vendor.module.product.customlist" 
      template="Vendor_Module::product/list/customlist.phtml">
<arguments>
 <argument name="type" xsi:type="string">customtype</argument>
 <argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Product\Listing\PreparePostData</argument>
</arguments>
<block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="customlist.product.addto" as="addto">
 <block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
        name="customlist.product.addto.compare" as="compare"
        template="Magento_Catalog::product/list/addto/compare.phtml"/>
 </block>
</block>
</referenceContainer>

This works as expected: I see my custom list with the child block for the AddTo section.

Now I want to create a widget for this list, so that we no longer need to reference some container via xml but we can add the list by simply adding the widget via backend.

Transforming my layout xml into a block widget has two issue:

  • I have to set a view_model
  • I have to set a child block for the addTo section

For the first issue, I simply replaced the view_model setting in the layout xml with a di in my block.

The second issue is the one I cannot overcome: how can I set the child block in the widget? I tried calling the block directly in the template phtml:

echo $this->getLayout()->createBlock('Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare')->setProduct($_item)->toHtml();
echo $this->getLayout()->createBlock('Magento\Catalog\Block\Product\ProductList\Item\Container')->setProduct($_item)->toHtml();

but none of them is working.

My widget.xml is very standard:

<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
    <widget class="Vendor\Module\Block\Widget\CustomList" id="vendor_module_widget">
        <label translate="true">Custom List Widget</label>
        <parameters>
          ...
        </parameters>
    </widget>
</widgets>

so it is my block:

namespace Vendor\Module\Block\Widget;

class CustomList extends Template implements BlockInterface
{
  ...
}

How can I add child blocks to my widget?

1
  • did you find any solution?
    – krybbio
    Jan 21, 2022 at 15:54

1 Answer 1

1

You can rely on the $this->addChild function to add a child block in Magento 2. Check the following example:

$this->addChild(
       'back_button',
       'Magento\Backend\Block\Widget\Button',
       ['label' => __('Back'), 'template' => 'Vendor_Moduel::template.phtml' 'class' => 'cancel']
   );

Then it is necessary to use

$this->getChildHtml('back_button')

in parent block template to render child block with the template. It’s better to utilize layout to define templates and blocks.

Your Answer

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

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