0

I want to show root category with it's child categories on home page. I've done my code so far, but nothing happens.

Vendor/Module/Block/CategoriesCollection.php

<?php
namespace Vendor\Module\Block;
class CategoriesCollection extends \Magento\Framework\View\Element\Template
{
protected $_categoryHelper;
protected $categoryFlatConfig;
protected $topMenu;
/**
 * @param \Magento\Framework\View\Element\Template\Context $context
 * @param \Magento\Catalog\Helper\Category $categoryHelper
 * @param array $data
 */
public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Helper\Category $categoryHelper,
    \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
    \Magento\Theme\Block\Html\Topmenu $topMenu
) {
    $this->_categoryHelper = $categoryHelper;
    $this->categoryFlatConfig = $categoryFlatState;
    $this->topMenu = $topMenu;
    parent::__construct($context);
}
/**
 * Return categories helper
 */
public function getCategoryHelper()
{
    return $this->_categoryHelper;
}
/**
 * Return top menu html
 * getHtml($outermostClass = '', $childrenWrapClass = '', $limit = 0)
 * example getHtml('level-top', 'submenu', 0)
 */
public function getHtml()
{
    return $this->topMenu->getHtml();
}
/**
 * Retrieve current store categories
 *
 * @param bool|string $sorted
 * @param bool $asCollection
 * @param bool $toLoad
 * @return \Magento\Framework\Data\Tree\Node\Collection|\Magento\Catalog\Model\Resource\Category\Collection|array
 */
public function getStoreCategories($sorted = false, $asCollection = false, $toLoad = true)
{
    return $this->_categoryHelper->getStoreCategories($sorted , $asCollection, $toLoad);
}
/**
 * Retrieve child store categories
 *
 */
public function getChildCategories($category)
{
    if ($this->categoryFlatConfig->isFlatEnabled() && $category->getUseFlatResource()) {
        $subcategories = (array)$category->getChildrenNodes();
    } else {
        $subcategories = $category->getChildren();
    }
    return $subcategories;
}
}

Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Ibnab\CategoriesSide\Block\CategorisCollection">
    <arguments>
        <argument name="deleteorderAction" xsi:type="array">
            <item name="context" xsi:type="string">\Magento\Framework\View\Element\Template\Context</item>
            <item name="helper" xsi:type="string">\Magento\Catalog\Helper\Category</item>
            <item name="flatstate" xsi:type="string">\Magento\Catalog\Model\Indexer\Category\Flat\State</item>
            <item name="menu" xsi:type="string">\Magento\Theme\Block\Html\Topmenu</item>
        </argument>
    </arguments>
</type>

Vendor/Module/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Vendor_Module" setup_version="1.0.0" schema_version="1.0.0">
    <sequence>
        <module name="Magento_Catalog"/>
    </sequence>
</module>

Vendor/Module/view/frontend/layout/cms_index_index.xml

<?xml version="1.0"?>

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<body>
    <referenceContainer name="sidebar.main">
        <block class="Vendor\Module\Block\CategoriesCollection" name="categoriescollection" template="Vendor_Module::storecategories.phtml"/>
    </referenceContainer>
</body>

Vendor/Module/view/frontend/template/storecategories.phtml

<?php
$categories = $this->getStoreCategories(true,false,true);
$categoryHelper = $this->getCategoryHelper();
?>
<ul>
    <?php
    foreach($categories as $category):
        if (!$category->getIsActive()) {
            continue;
        }
        ?>
        <li><a href="<?php echo $categoryHelper->getCategoryUrl($category) ?>"><?php echo $category->getName() ?></a></li>
        <?php
        if($childrenCategories = $this->getChildCategories($category)):
            ?>
            <ul>
                <?php
                foreach($childrenCategories as $childrenCategory):
                    if (!$childrenCategory->getIsActive()) {
                        continue;
                    }
                    ?>
                    <li><a href="<?php echo $categoryHelper->getCategoryUrl($childrenCategory) ?>"><?php echo $childrenCategory->getName() ?></a></li>
                <?php
                endforeach;
                ?>
            </ul>
        <?php
        endif;
    endforeach;
    ?>
</ul>

Vendor/Module/registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_Module',
__DIR__
);

How can I display root category, for example ID65, with it's subcategories?

1 Answer 1

0

I have to do something similar and I have used following code to achieve the requirement.

app/code/Anshu/CategoryFilter/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Anshu_CategoryFilter',
    __DIR__
);

app/code/Anshu/CategoryFilter/etc/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="Anshu_CategoryFilter" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

app/code/Anshu/CategoryFilter/Block/CategoryFilter.php

<?php

namespace Anshu\CategoryFilter\Block;

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

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

    /**
     * @var \Magento\Catalog\Model\Indexer\Category\Flat\State
     */
    protected $categoryFlatConfig;

    /**
     * @var \Magento\Catalog\Model\CategoryFactory
     */
    protected $_categoryFactory;

    /**
     * @param Template\Context                                        $context
     * @param \Magento\Catalog\Helper\Category                        $categoryHelper
     * @param \Magento\Catalog\Model\Indexer\Category\Flat\State      $categoryFlatState
     * @param \Magento\Catalog\Model\CategoryFactory                  $categoryFactory
     * @param array                                                   $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
        $data = []
    )
    {
        $this->_categoryHelper           = $categoryHelper;
        $this->categoryFlatConfig        = $categoryFlatState;
        $this->_categoryFactory          = $categoryFactory;
        parent::__construct($context, $data);
    }

    /**
     * Get all categories
     *
     * @param bool $sorted
     * @param bool $asCollection
     * @param bool $toLoad
     *
     * @return array|\Magento\Catalog\Model\ResourceModel\Category\Collection|\Magento\Framework\Data\Tree\Node\Collection
     */
    public function getCategories($sorted = false, $asCollection = false, $toLoad = true)
    {
        $cacheKey = sprintf('%d-%d-%d-%d', $this->getSelectedRootCategory(), $sorted, $asCollection, $toLoad);
        if ( isset($this->_storeCategories[ $cacheKey ]) )
        {
            return $this->_storeCategories[ $cacheKey ];
        }
        /**
         * Check if parent node of the store still exists
         */
        $category = $this->_categoryFactory->create();

        $storeCategories = $category->getCategories($this->getSelectedRootCategory(), $recursionLevel = 0, $sorted, $asCollection, $toLoad);
        $this->_storeCategories[ $cacheKey ] = $storeCategories;
        return $storeCategories;
    }

    /**
     * Get current store root category id
     *
     * @return int|mixed
     */
    public function getSelectedRootCategory()
    {
        return $this->_storeManager->getStore()->getRootCategoryId();
    }

    /**
     * @param        $category
     * @param string $html
     * @param int    $level
     *
     * @return string
     */
    public function getChildCategoryView($category, $html = '', $level = 1)
    {   
        // Check if category has children
        if ( $category->hasChildren() )
        {  
            $childCategories = $this->getSubcategories($category);
            $childCount = (int)$category->getChildrenCount();
            if ( $childCount > 0 )
            {   
                $html .= '<ul class="o-list o-list--unstyled" style="display:none">';
                // Loop through children categories
                foreach ( $childCategories as $childCategory )
                {
                    $html .= '<li class="level' . $level . '">';
                    $html .= '<a href="' . $this->getCategoryUrl($childCategory) . '" title="' . $childCategory->getName() . '">' . $childCategory->getName() . '</a>';
                    if ($childCategory->hasChildren())
                    {
                        $html .= '<span class="expand"><i class="fa fa-plus">+/-</i></span>';
                        $html .= $this->getChildCategoryView($childCategory, '', ($level + 1));
                    }

                    $html .= '</li>';
                }
                $html .= '</ul>';
            }
        }
        return $html;
    }

    /**
     * Retrieve subcategories
     * 
     * @param $category
     *
     * @return array
     */ 
    public function getSubcategories($category)
    {
        if ($this->categoryFlatConfig->isFlatEnabled() && $category->getUseFlatResource()) {
            $subcategories = (array)$category->getChildrenNodes();
        } else {
            $subcategories = $category->getChildren();
        }
        return $subcategories;
    }

    /**
     * Return Category URL
     *
     * @param $category
     *
     * @return string
     */
    public function getCategoryUrl($category)
    {
        return $this->_categoryHelper->getCategoryUrl($category);
    }
}

app/code/Anshu/CategoryFilter/view/frontend/requirejs-config.js

var config = {
    map: {
        '*': {
            categoryfilter: 'Anshu_CategoryFilter/js/categoryfilter'
        }
    }
};

app/code/Anshu/CategoryFilter/view/frontend/web/js/categoryfilter.js

require(['jquery'], function ($) {
    $(function () {
        $('.category-heading').on('click', function () {
            $('.category-filter').toggle();
        });
        $('.category-filter').on('click', '.o-list .expand, .o-list .expanded', function () {
            var element = $(this).parent('li');
            if (element.hasClass('active')) {
                element.find('ul:first').slideUp();
                element.removeClass('active');
            } else {
                element.addClass('active');
                element.children('ul').slideDown();
                element.parent('ul').find('i').addClass('fa-plus');
                element.find('> span i').addClass('fa-minus');
            }
        });
    });
});

app/code/Anshu/CategoryFilter/view/frontend/templates/categoryfilter.phtml

<?php
$categories = $block->getCategories();
?>
<div class="category-filter-area">
    <div class="filter-heading">
        <h3><?php echo __('CATEGORY'); ?></h3>
    </div>
    <div class="category-filter">
        <ul class="o-list">
            <?php
            // Loop through categories
            foreach ( $categories as $category ) {
                ?>
                <li class="level0">
                    <a href="<?php echo $block->getCategoryUrl($category); ?>" title="<?php echo $category->getName(); ?>">
                        <?php echo $category->getName(); ?>
                    </a>
                    <?php if ( $category->hasChildren() ) { ?>
                        <span class="expand"><i class="fa fa-plus">+/-</i></span>
                    <?php } ?>

                    <?php echo $block->getChildCategoryView($category, $html = '', $level = $category->getLevel() + 1); ?>
                </li>
            <?php } ?>
        </ul>
    </div>
</div>    
<script type="text/javascript">
    require(['jquery','categoryfilter'], function () {});
</script>

You can modify this code according to your requirement. I hope this will be helpful.

I have to show this block on cms page, so I have called it in CMS page in admin. You can call this or show this block at any place you want.

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.