The product grid of a category page (frontend) is rendered via layout in catalog_category_view.xml.

Lets say I have a custom product collection (which I got via

ProductRepositoryInterface::getList($searchCriteria) method

in a custom block class and want to render this collection. The rendered result should be displayed as a product grid on frontend (just like any category page).

How can this be done ?

By looking into catalog_category_view.xml there are two significant lines, which are responsible for rendering a product collection:

<block class="Magento\Catalog\Block\Category\View" name="category.products" template="Magento_Catalog::category/products.phtml">
<block class="Magento\Catalog\Block\Product\ListProduct" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">

How can I provide my custom product collection to these template files, so they render my collection ?

Correct me, if I am wrong on this.

This is how my block code looks like:

namespace Mod\Mod1\Block;
use Magento\Framework\View\Element\Template;
class Main extends Template
protected $_filterBuilder;
protected $_filterGroupArray;
protected $_filterGroupBuilder;
protected $_searchCriteriaBuilder;
protected $_productRepository;
protected $_productFactory;
protected $_list;

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
    \Magento\Framework\Api\Search\FilterGroupBuilder $filterGroupBuilder,
    \Magento\Framework\Api\FilterBuilder $filterBuilder,
    \Magento\Catalog\Model\ProductFactory $productFactory,
    array $data = [])
    $this->_productRepository = $productRepository;
    $this->_searchCriteriaBuilder = $searchCriteriaBuilder;
    $this->_filterGroupBuilder = $filterGroupBuilder;
    $this->_filterBuilder = $filterBuilder;
    parent::__construct($context, $data);

public function getLoadedProductCollection(){
    $searchCrit = $this->buildSearchCriteria('','','','','','5-',1);
    $list = $this->_productRepository->getList($searchCrit);
    return $list;
public function buildSearchCriteria(...){
return $searchCriteria;
  • 1
    Are you asking how to replace products on a category page or how to essentially have another version of the category controller? Sep 19, 2017 at 15:40
  • Pagination and layer navigation never come right if you edit collection in list.phtml or corresponding block. So make sure the answer you're accepting does both of the things above.Regards. Sep 22, 2017 at 7:22

4 Answers 4


You can try this:

Update your catalog_category_view.xml

<block class="Magento\Catalog\Block\Product\ListProduct" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">
<block class="Your(Mod)\Namespace(Mod1)\Block\YourBlockFileName(Main)" name="your.category.products.list" template="Magento_Catalog::product/yourFile.phtml" />

And call yourFile.phtml in product/list.phtml:

<?php echo $this->getChildHtml('your.category.products.list'); ?>

Now, you can use your function in yourfile.phtml like this:




Hope this can help you.


The best approach would be:

Update your catalog_category_view.xml and replace Magento\Catalog\Block\Product\ListProduct with Mod\Mod1\Block\Main


<block class="Magento\Catalog\Block\Product\ListProduct" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">


block class="Mod\Mod1\Block\Main" name="category.products.list" as="product_list" template="Magento_Catalog::product/list.phtml">

Your Main class MUST extend Magento\Catalog\Block\Product\ListProduct

Then you will need to rewrite the method getLayer() to your own.

FYI: your class Mod\Mod1\Block\Main needs some refactoring.

Create your own new Layer class that will extend Magento\Catalog\Model\Layer and play around with the collections.

 * Retrieve current layer product collection
 * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
public function getProductCollection()


 * Initialize product collection
 * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
 * @return \Magento\Catalog\Model\Layer
public function prepareProductCollection($collection)
  • Where is the block here? What is in Mod\Mod1\Block\Main.php? Jul 29, 2020 at 2:05

Basically initially you want to create a controller or even a basic CMS page so you have a page to show your collection.

From there you can use your custom block which creates your collection combined with the list.phtml template file to render the products on your page.

{{block class="Vendor\Module\Block\ProductCollection" template="Magento_Catalog::product/list.phtml" name="specialproducts"}} 

Add above xml where Vendor\Module\Block\ProductCollection is the custom block code where your collection is created to xml for that page.

The list.phtml file gathers the collection from your block with below line of code:

$_productCollection = $block->getLoadedProductCollection();

So long as your block has the getLoadedProductCollection() function returning your collection of products the list.phtml file will then loop through each product in your collection rendering them in a default Magento product grid.

For your block code try updating below line to include getItems():

$list = $this->_productRepository->getList($searchCrit)->getItems();
  • I did as you said. My block has the ' getLoadedProductCollection()' function which returns 'ProductRepositoryInterface::getList()'. But I get an Error : Uncaught Error: Call to undefined method Magento\Framework\Api\SearchResults::count() in ... Looks like this is not the right approach. Sep 21, 2017 at 14:09
  • see updated post Sep 21, 2017 at 14:59
  • Maybe try changing $list = $this->_productRepository->getList($searchCrit)->getItems();
    – harri
    Sep 21, 2017 at 15:40
  • @shahirhajir Did you try with getItems?
    – harri
    Sep 25, 2017 at 13:20
  • Not working. $list = $this->_productRepository->getList($searchCrit)->getItems(); returns ProductInterface[] array and this array has no count() funtion. Uncaught Error: Call to a member function count() on array in ...\list.phtml on line 22. On line 22 in list.phtml we have: $_productCollection->count() Sep 25, 2017 at 20:46

You can render product collection in your phtml file like this

$product_collection = $block->getLoadedProductCollection();

  • Not helpful at all Sep 25, 2017 at 20:32
  • not helpful . .
    – user98255
    Dec 3, 2021 at 9:06
  • To make this answer complete, you should share how getLoadedProductCollection() is defined inside your Block class, as well as sharing any other definitions on which this function depends. Additionally, you should display the structure of all files shared.
    – Muckee
    Aug 7, 2022 at 9:58

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.