11

I want to create all product page with the filters, toolbar, pagination.

I can do it by creating a new category with the name All Products and assign all products in it. But I guess this is not a good approach, as if every time new products added to the website it should also be added to All Products category. There is a lot of chances of human error.

Is there a way of calling a category page with the root level category? like from ID: 2

It's okay if anyone doesn't want to write code for me, but if anyone can help me find an approach to do it that would be great.

1 Answer 1

13
+150

I recently did the same sort of work. First you need to override Category block because you want the All products page just like category page. In order to, get more understanding check getCurrentCategory() function which set the current category to root category

Path: app\code\Vendor\AllProducts\Block\Category\View.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Vendor\AllProducts\Block\Category;

/**
 * Class View
 * @api
 * @package Magento\Catalog\Block\Category
 * @since 100.0.2
 */
class View extends \Magento\Catalog\Block\Category\View
{
    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $_coreRegistry = null;

    /**
     * Catalog layer
     *
     * @var \Magento\Catalog\Model\Layer
     */
    protected $_catalogLayer;

    /**
     * @var \Magento\Catalog\Helper\Category
     */
    protected $_categoryHelper;

    protected $priceHelper;

    protected $_storeManager;

    protected $categoryRepository;

    protected $_request;

    protected $productFactory;

    protected $eavconfig;   
    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Catalog\Helper\Category $categoryHelper
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        \Magento\Framework\Registry $registry,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Framework\Pricing\Helper\Data $priceHelper,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\CategoryRepository $categoryRepository,
        \Magento\Framework\App\Request\Http $request,
        \Magento\Catalog\Model\ResourceModel\ProductFactory $productFactory,
        \Magento\Eav\Model\Config $eavconfig,
        array $data = []
    ) {
        $this->_categoryHelper = $categoryHelper;
        $this->priceHelper = $priceHelper;
        $this->_catalogLayer = $layerResolver->get();
        $this->_coreRegistry = $registry;
        $this->_storeManager = $storeManager;
        $this->_request = $request;
        $this->categoryRepository = $categoryRepository;
        $this->productFactory = $productFactory;
        $this->eavconfig = $eavconfig;

        parent::__construct($context, $layerResolver, $registry, $categoryHelper, $data);
    }

    /**
     * @return $this
     */
    protected function _prepareLayout()
    {
        parent::_prepareLayout();


        $this->getLayout()->createBlock(\Magento\Catalog\Block\Breadcrumbs::class);

        $category = $this->getCurrentCategory();
        if ($category) {
            $title = $category->getMetaTitle();
            if ($title) {
                $this->pageConfig->getTitle()->set($title);
            }
            $description = $category->getMetaDescription();
            if ($description) {
                $this->pageConfig->setDescription($description);
            }
            $keywords = $category->getMetaKeywords();
            if ($keywords) {
                $this->pageConfig->setKeywords($keywords);
            }
            if ($this->_categoryHelper->canUseCanonicalTag()) {
                $this->pageConfig->addRemotePageAsset(
                    $category->getUrl(),
                    'canonical',
                    ['attributes' => ['rel' => 'canonical']]
                );
            }

            $pageMainTitle = $this->getLayout()->getBlock('page.main.title');
            if ($pageMainTitle) {
                $pageMainTitle->setPageTitle($this->getCurrentCategory()->getName());
            }
        }

        return $this;
    }

    /**
     * @return string
     */
    public function getProductListHtml()
    {
        return $this->getChildHtml('product_list');
    }

    /**
     * Retrieve current category model object
     *
     * @return \Magento\Catalog\Model\Category
     */

    //**** This function set the current category to root level category which is 2 in my case ****//
    public function getCurrentCategory()
    {
        if (!$this->hasData('current_category')) {

            if ($this->_request->getModuleName() == "allproducts"){
            $category = $this->categoryRepository->get(2, $this->_storeManager->getStore()->getId());
            }
            else {
            $category = $this->_coreRegistry->registry('current_category');
            }
            $this->setData('current_category', $category);
        }

        return $this->getData('current_category');
    }

    /**
     * @return mixed
     */
    public function getCmsBlockHtml()
    {
        if (!$this->getData('cms_block_html')) {
            $html = $this->getLayout()->createBlock(
                \Magento\Cms\Block\Block::class
            )->setBlockId(
                $this->getCurrentCategory()->getLandingPage()
            )->toHtml();
            $this->setData('cms_block_html', $html);
        }
        return $this->getData('cms_block_html');
    }

    /**
     * Check if category display mode is "Products Only"
     * @return bool
     */
    public function isProductMode()
    {
        return $this->getCurrentCategory()->getDisplayMode() == \Magento\Catalog\Model\Category::DM_PRODUCT;
    }

    /**
     * Check if category display mode is "Static Block and Products"
     * @return bool
     */
    public function isMixedMode()
    {
        return $this->getCurrentCategory()->getDisplayMode() == \Magento\Catalog\Model\Category::DM_MIXED;
    }

    /**
     * Check if category display mode is "Static Block Only"
     * For anchor category with applied filter Static Block Only mode not allowed
     *
     * @return bool
     */
    public function isContentMode()
    {
        $category = $this->getCurrentCategory();
        $res = false;
        if ($category->getDisplayMode() == \Magento\Catalog\Model\Category::DM_PAGE) {
            $res = true;
            if ($category->getIsAnchor()) {
                $state = $this->_catalogLayer->getState();
                if ($state && $state->getFilters()) {
                    $res = false;
                }
            }
        }
        return $res;
    }

    /**
     * Return identifiers for produced content
     *
     * @return array
     */
    public function getIdentities()
    {
        return $this->getCurrentCategory()->getIdentities();
    }
}

Add block Path: app\code\Vendor\AllProducts\Block\Index\Index.php

<?php

namespace Vendor\AllProducts\Block\Index;


class Index extends \Magento\Framework\View\Element\Template {

    public function __construct(\Magento\Catalog\Block\Product\Context $context, array $data = []) {

        parent::__construct($context, $data);

    }


    protected function _prepareLayout()
    {
        return parent::_prepareLayout();
    }

}

Add Front controller, path should be like: app\code\Vendor\AllProducts\Controller\Index\Index.php

<?php

namespace Vendor\AllProducts\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action
{
    private $context;
    private  $response;
    private  $redirect;
    /**
     * @var \Magento\Framework\UrlInterface
     */
    private $url;


    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\UrlInterface $url
    )
    {
        parent::__construct($context);
        $this->context = $context;
        $this->response = $context->getResponse();
        $this->redirect = $context->getRedirect();
        $this->url = $url;
        //return 
    }

    public function execute()
    {

        $this->_view->loadLayout();
        $this->_view->getLayout()->initMessages();
        $this->_view->renderLayout();
    }

    public function getResponse()
    {
        return $this->response;
    }
}

Add di.xml in your module for overriding guidance Path: app\code\Vendor\AllProducts\etc\di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Block\Category\View" type="Vendor\AllProducts\Block\Category\View" />
</config>

Override catalog_category_view.xml in your module. Path should be like: app\code\Vendor\AllProducts\view\frontend\layout\allproducts_index_index.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
       <referenceContainer name="sidebar.main">
            <block class="Magento\LayeredNavigationStaging\Block\Navigation\Category" name="catalog.leftnav" before="-" template="Magento_LayeredNavigation::layer/view.phtml">
                <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalog.navigation.state" as="state" />
                <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalog.navigation.renderer" as="renderer" template="Magento_LayeredNavigation::layer/filter.phtml"/>
            </block>
        </referenceContainer>
        <referenceContainer name="content">
            <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">
                    <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" name="category.product.type.details.renderers.default" 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>
            </block>
        </referenceContainer>
    </body>
</page>

I hope this will help

5
  • Thanks Muhammad, Let me try this solution. Commented Jun 14, 2019 at 7:05
  • Thanks worked for me :) Commented Jun 14, 2019 at 9:00
  • @MuhammadHasham It's layout display wrong and swatches and layered navigation also not display. How to solve it? Commented Oct 16, 2019 at 17:46
  • Can you please help me here? magento.stackexchange.com/q/292878/77631 Commented Oct 16, 2019 at 18:14
  • @MuhammadHasham I want to display child category also in category list. Do you know how to display that? I display "Default category" in all product page. Commented Dec 4, 2019 at 12:52

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.