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?