Here is an example module that will allow you specify a product collection for a customized product list element, which you should be able to adapt to your needs. It works by extending the ListProduct
class to allow it's backing collection to be set dynamically.
File Structure:
app/code/AAllen/CustomProdList
|
| registration.php
|
+---Block
| \---Product
| CustomList.php
|
+---Controller
| \---Index
| Index.php
|
+---etc
| | module.xml
| |
| \---frontend
| routes.xml
|
\---view
\---frontend
\---layout
customprodlist_index_index.xml
registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'AAllen_CustomProdList',
__DIR__
);
CustomList.php
is where we extend ListProduct
by overriding the GetLoadedProductCollection
method and adding a method to set the product collection.
<?php
namespace AAllen\CustomProdList\Block\Product;
use Magento\Catalog\Block\Product\ListProduct;
use Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection;
class CustomList extends ListProduct
{
public function getLoadedProductCollection()
{
return $this->_productCollection;
}
public function setProductCollection(AbstractCollection $collection)
{
$this->_productCollection = $collection;
}
}
Index.php
is an example of a controller where we set a product collection on the CustomList
block which will be placed in the layout file.
<?php
namespace AAllen\CustomProdList\Controller\Index;
use AAllen\CustomProdList\Block\Product\CustomList;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Index extends Action
{
/** @var PageFactory */
protected $pageFactory;
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection */
protected $productCollection;
public function __construct(
Context $context,
PageFactory $pageFactory,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory
)
{
$this->pageFactory = $pageFactory;
$this->productCollection = $collectionFactory->create();
parent::__construct($context);
}
public function execute()
{
$result = $this->pageFactory->create();
// obtain product collection.
$this->productCollection->addIdFilter(5); // do some filtering
$this->productCollection->addFieldToSelect('*');
// get the custom list block and add our collection to it
/** @var CustomList $list */
$list = $result->getLayout()->getBlock('custom.products.list');
$list->setProductCollection($this->productCollection);
return $result;
}
}
module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="AAllen_CustomProdList" setup_version="1.0.0">
<sequence>
<module name="Magento_Catalog"/>
</sequence>
</module>
</config>
routes.xml
defines an example route where we want to display the product list.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="customprodlist" frontName="customprodlist">
<module name="AAllen_CustomProdList"/>
</route>
</router>
</config>
customprodlist_index_index.xml
is the layout for the above route. This is where we place our block element as well as some child blocks which I copied from catalog_category_view.xml
.
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Custom Product List</title>
</head>
<body>
<referenceContainer name="content">
<block class="AAllen\CustomProdList\Block\Product\CustomList" name="custom.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">
<container name="category.product.list.additional" as="additional" />
<block class="Magento\Framework\View\Element\RendererList" name="category.product.type.details.renderers" as="details.renderers">
<block class="Magento\Framework\View\Element\Template" as="default"/>
</block>
<block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="category.product.addto" as="addto">
<block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
name="category.product.addto.compare" as="compare"
template="Magento_Catalog::product/list/addto/compare.phtml"/>
</block>
<block class="Magento\Catalog\Block\Product\ProductList\Toolbar" name="product_list_toolbar" template="Magento_Catalog::product/list/toolbar.phtml">
<block class="Magento\Theme\Block\Html\Pager" name="product_list_toolbar_pager"/>
</block>
<action method="setToolbarBlockName">
<argument name="name" xsi:type="string">product_list_toolbar</argument>
</action>
</block>
</referenceContainer>
</body>
</page>