There's a few posts regarding how to get a list of categories in Magento 2, but they all seem to require getting the current category.

I'm looking for a php solution to show a list of all categories on every page, so I need a solution that doesn't require checking the current category. My goal is to create a custom navigation menu with 3 layers of sub-category depth.

Is there anyway I can get these lists with a foreach statement in a custom template block?


This is the error I am receiving with the answer:

1 exception(s): Exception #0 (Magento\Framework\Exception\LocalizedException): The "is_enable_attribute11" attribute name is invalid. Reset the name and try again.

Exception #0 (Magento\Framework\Exception\LocalizedException): The "is_enable_attribute11" attribute name is invalid. Reset the name and try again.


1 Answer 1


Here i create category list, category show in list which is enable for listing ( Custom attribute into Category Form).

for enable and disable i create custom category attribute. and enable category show in list.




namespace VendoreName\ModuleName\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface

    protected $eavSetupFactory;

    public function __construct(\Magento\Eav\Setup\EavSetupFactory $eavSetupFactory)
        $this->eavSetupFactory = $eavSetupFactory;

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)

        if (version_compare($context->getVersion(), '0.0.1', '<=')) {

            $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

                            'type'     => 'int',
                            'label'    => 'Display Category in List',
                            'input'    => 'Boolean',
                            'source'   => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean',
                            'visible'  => true,
                            'required' => false,
                            'global'   => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                            'group' => 'General Information',



InstallData.php file run only one time when your module is installing first time. app\code\VendoreName\ModuleName\view\adminhtml\ui_component


<?xml version="1.0" encoding="UTF-8"?>

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <fieldset name="general">
        <field name="is_enable_attribute11">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="dataType" xsi:type="string">boolean</item>
                    <item name="formElement" xsi:type="string">checkbox</item>
                    <item name="label" xsi:type="string" translate="true">Display Category in List</item>
                    <item name="prefer" xsi:type="string">toggle</item>
                        <item name="valueMap" xsi:type="array">
                            <item name="true" xsi:type="string">1</item>
                            <item name="false" xsi:type="string">0</item>




namespace VendoreName\ModuleName\Block;

use Magento\Catalog\Model\Product;

class Categorylist extends \Magento\Framework\View\Element\Template
    protected $_categoryFactory;

    protected $_storeManager;

    protected $_categoryNameFactory;    

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\CategoryFactory $categoryNameFactory,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $collecionFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Registry $registry,
        array $data = []
        $this->_coreRegistry = $registry;
        $this->_categoryNameFactory = $categoryNameFactory;
        $this->_categoryFactory = $collecionFactory;
        $this->_storeManager = $storeManager;
        parent::__construct($context, $data);

    public function getEnableCategory()

        $category = $this->_categoryFactory->create()->addAttributeToFilter('is_enable_attribute11',1)->setStore($this->_storeManager->getStore());
        return $category;

    public function getCategoryName($categoryId)
        $category = $this->_categoryNameFactory->create()->load($categoryId)->setStore($this->_storeManager->getStore());
        return $category;



$category = $block->getEnableCategory();
<h1 align="center">Category  list</h1>
<div class="category-show-main">
  <div class="swiper-container">
    <div class="swiper-wrapper">
      <?php foreach($category as $categorydata) : ?>
          $categoryid = $categorydata->getEntityId();
          $categoryFactory = $block->getCategoryName($categoryid);
          $categoryNameshow = $categoryFactory->getName();
          $categoryUrlShow = $categoryFactory->getUrl();
        <div class="swiper-slide main-category-show-slide">
          <a class="category-link-show" href="<?php echo $categoryUrlShow; ?>" alt="<?php echo $categoryNameshow; ?>" title="<?php echo $categoryNameshow; ?>" >
            <div class="category-show-cmspage">
                <div class="category-slide">
                        <div class="category-name-show"><?php echo $categoryNameshow; ?></div>
      <?php endforeach; ?> 
    <!-- Add Pagination -->
    <div class="blank-div">&nbsp;</div>
    <div class="swiper-pagination"></div>
     <!-- Add Arrows -->
    <div class="swiper-button-next"></div>
    <div class="swiper-button-prev"></div>
<script type="text/javascript">// <![CDATA[
(function  () {    
    require(['jquery', 'swiperjs'], function($,swiperjs) {
        $(document).ready(function($) {
            var swiper = new swiperjs('.swiper-container', {
                    slidesPerView: 4,
                  spaceBetween: 15,
                  loop: false,
                  pagination: {
                    el: '.swiper-pagination',
                    clickable: true,
                  navigation: {
                    nextEl: '.swiper-button-next',
                    prevEl: '.swiper-button-prev',
// ]]></script>

Add this in your layout file where you want to show category list. And if you want to show all pages add this into default.xml

<block class="VendoreName\ModuleName\Block\Categorylist" template="VendoreName_ModuleName::category.phtml"/>

and for slider i used swiper so add this js file also in your layout

     <css src="VendoreName_ModuleName::css/swiper.min.css"/> 

I Hope This Helps You.

  • Thank you for this answer! I will test this code and let you know my results!
    – Sam Assoum
    Feb 13, 2020 at 21:34
  • Do I need to create a routers.xml file and controller for this module?
    – Sam Assoum
    Feb 14, 2020 at 14:54
  • Yes you need to create route.xml for show your category list on frontend layout page
    – Msquare
    Feb 14, 2020 at 16:43
  • Let me inform above solution is works for you ??
    – Msquare
    Feb 14, 2020 at 16:44
  • 1
    Let me inform me once you did it ? And if you have any Query you can ask here.
    – Msquare
    Feb 14, 2020 at 18:05

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.