Magento 2 – How to Call Widget with Products of Specific Category in .phtml File

magento2phtmlwidget

How can I call a widget that displays product from a specific category in a phtml file?

Currently I can only display "all_products" in my phtml file like that:

echo $this->getLayout()->createBlock("Magento\Catalog\Block\Product\Widget\NewWidget")->setDisplayType("all_products")->setProductsCount("5")->setTemplate("product/widget/new/content/new_grid.phtml")->toHtml();

How to do this with products from specific category and not all products?

Best Answer

There is a widget for arbitrary product lists (as mentioned by @Nits). If you insert the widget on any CMS page or block and turn off the WYSIWYG editor ("Hide editor" button), you can see how the parameters look like.

For example, I created the widget with the condition "category = 4", showing five products:

{{widget type="Magento\CatalogWidget\Block\Product\ProductsList" title="My products" products_count="5" template="product/widget/content/grid.phtml" conditions_encoded="a:2:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:12:`category_ids`;s:8:`operator`;s:2:`==`;s:5:`value`;s:1:`4`;]]"}}

From that you can see that the class is Magento\CatalogWidget\Block\Product\ProductsList and you can create it programmatically as follows:

$productsBlock = $this->getLayout()->createBlock(\Magento\CatalogWidget\Block\Product\ProductsList::class);
$productsBlock->setTitle("My products");
$productsBlock->setProductsCount(5);
$productsBlock->setTemplate("product/widget/content/grid.phtml");
$productsBlock->setConditionsEncoded("a:2:[i:1;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Combine`;s:10:`aggregator`;s:3:`all`;s:5:`value`;s:1:`1`;s:9:`new_child`;s:0:``;]s:4:`1--1`;a:4:[s:4:`type`;s:50:`Magento|CatalogWidget|Model|Rule|Condition|Product`;s:9:`attribute`;s:12:`category_ids`;s:8:`operator`;s:2:`==`;s:5:`value`;s:1:`4`;]]");

But "conditions_encoded" is a serialized array (with some characters replaced for WYSIWYG compatibility). This serialized array is difficult to construct manually, but luckily you can also use "conditions" with the unserialized value instead in PHP code. So you can replace the last line from above with:

$productsBlock->setConditions(
    [
        1 => [
            'type' => \Magento\CatalogWidget\Model\Rule\Condition\Combine::class,
            'aggregator' => 'all',
            'value' => '1',
            'new_child' => '',
        ],
        '1-1' => [
            'type' => \Magento\CatalogWidget\Model\Rule\Condition\Product::class,
            'attribute' => 'category_ids',
            'operator' => '==',
            'value' => '4',
        ]
    ]
);

Then output:

echo $productsBlock->toHtml();