I want to display subcategory in category page with the image. I've to put below code get only subcategory name not getting the image.

How to get subcategory image in category page?




                foreach($subcategories as $subcategory){

                      <a href="<?php echo $subcategory->getRequest_path(); ?>"><?php echo $subcategory->getName() ?></a>

  • use this $subcategory->getImageUrl(); – MagikVishal Jun 15 '16 at 9:19
  • Also Use $subcategory->getImageUrl(); code to GetImageUrl but not getting Image url. – Nikul Jun 15 '16 at 10:00

i used this block to have the same functionality and called the block in xml ( don't forget to create a template for the block with the desired functionality and html mockup

namespace Namespace\Module_Name\Block;

class Subcategories extends \Magento\Framework\View\Element\Template

     * @var \Magento\Framework\Registry
    protected $_registry;

     * @var \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
    protected $_categoryCollectionFactory;

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

     * Subcategories constructor.
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory
     * @param \Magento\Catalog\Helper\Category $categoryHelper
     * @param \Magento\Framework\Registry $registry
     * @param array $data
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Framework\Registry $registry,
        array $data = []
        $this->_registry = $registry;
        $this->_categoryCollectionFactory = $categoryCollectionFactory;
        $this->_categoryHelper = $categoryHelper;
        parent::__construct($context, $data);

    public function getCurrentCategory()
        return $this->_registry->registry('current_category');

    public function getCategoryCollection(){
        $_category = $this->getCurrentCategory();
        $collection = $this->_categoryCollectionFactory->create();
            ->addAttributeToFilter('is_active', 1)
            ->setOrder('position', 'ASC')

        return $collection;


If you are on product listing page than its quite easy to get image url

    if($subcategories) :
      foreach($subcategories as $subcategory) :
             $cat = $objectManager->create('Magento\Catalog\Model\Category')->load($subcategory->getId());
             echo $cat->getImageUrl()

// @codingStandardsIgnoreFile Default Magento Product listing page using $objectManager. so using of it we can load subcategory & done.


I did this by creating a preference for Magento\Model\ResourceModel\Category and an observer for Magento\Model\ResourceModel\Category\Flat.

Create a Module






<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="{vendor_name}_{module_name}" setup_version="1.0.0"></module>


<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Model\ResourceModel\Category" type="{vendor_name}\{module_name}\{path_to_class i.e Model\ResourceModel\Category}" />

I've just used the same name as the file this is taking precedence over but this is optional.


namespace {vendor_name}\{module_name}\Model\ResourceModel;

class Category extends \Magento\Catalog\Model\ResourceModel\Category
    /* Override this method */

    public function getChildrenCategories($category)
        $collection = $category->getCollection();
        /* @var $collection 
        \Magento\Catalog\Model\ResourceModel\Category\Collection */

        /* Add this section to select image */
        /* Add this section to select image */


        return $collection;

Ideally I would have used a plugin here, but sadly because of how this method is defined I don't see how I can.

I used Magento_Catalog/template/category/description.phtml to output my subcategories, I'm using the category main image as a thumbnail.

<?php if ($_description = $_category->getDescription()): ?>
<div class="category-description">
    <?php /* @escapeNotVerified */ echo $this->helper('Magento\Catalog\Helper\Output')->categoryAttribute($_category, $_description, 'description') ?>
<?php endif; ?>

<?php if($_category->hasChildren()): ?>
   <div class="categories wrapper grid categories-grid">
       <ul class="categories list items categories-items">
           <?php foreach($_category->getChildrenCategories() as $_child): ?>
               <?php if($_child->getIsActive()): ?>
                   <li class="item category category-item">
                       <?php if($_child->getImageUrl()): ?> <!-- We can now use getImageUrl() on child categories -->
                           <a href="<?php echo $_child->getUrl() ?>" class="category photo category-item-photo" tabindex="-1">                        
                                <span class="category-image-container">
                                    <span class="category-image-wrapper" style="padding-bottom: 125%;">
                                        <img class="category-image-photo" src="<?php echo $_child->getImageUrl(); ?>" alt="<?php /* @escapeNotVerified */ echo $this->helper('Magento\Catalog\Helper\Output')->categoryAttribute($_child, $_child->getName(), 'name') ?>" />
                        <?php endif; ?>
                        <strong class="category name category-item-name">
                            <a class="category-item-link" href="<?php echo $_child->getUrl() ?>"><?php /* @escapeNotVerified */ echo $this->helper('Magento\Catalog\Helper\Output')->categoryAttribute($_child, $_child->getName(), 'name') ?></a>
                <?php endif; ?>
            <?php endforeach; ?>
<?php endif; ?>

This works great for EAV mode but doesn't work in flat category mode, to fix that we need to create an observer, oddly Magento provides a hook/event to modify the database query in flat category mode, but not in EAV mode.



I've used frontend here as I'm only interested in observing this event on the frontend.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_category_flat_loadnodes_before">
    <observer name="{uour_unique_observer_name}" instance="{vendor_name}/{module_name}/Observer/{Whatever i.e CategoryFlatObserver}" />

Finally an observer class


i.e FlatCategoryObserver.php}`

namespace {vendor_name}\{module_name}\Observer;

use Magento\Framework\Event\ObserverInterface;

class CategoryFlatObserver implements ObserverInterface
    public function execute(\Magento\Framework\Event\Observer $observer)
        $select = $observer->getData('select');

Now anywhere the category resource model and getChildrenCategories() method is used on the frontend it will select the category image. Need to do a setup:upgrade and clear all caches before this will work.

  • Did all this and it's still returning null. Made sure I fixed all the broken code too (no php or xml opening tags and the missing endif in your description.phtml) – Octoxan Feb 28 '18 at 15:44
  • @Octoxan no need for that tone, I copied and pasted this from my file, I must have missed copying the the final endif in description. The rest of it is intentional, anyone wanting to mess around with the code should know they need PHP and XML tags. I assume you changed all of the {vendor_name}/{module_name} instances to whatever yours is? Did you do setup:upgrade to register the new module and clear cache etc. – 4D1 Apr 6 '18 at 14:35

I have Put Below Code Magento_Catalog/templates/category/products.phtml File and Get all Subcategory Images and Data.

$_helper    = $this->helper('Magento\Catalog\Helper\Output');
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $category = $objectManager->get('Magento\Framework\Registry')->registry('current_category');
    $childcategories = $category->getChildrenCategories();
    $sub_category_count = count($childcategories);

if($sub_category_count != 0){
echo '<ul>';
foreach($childcategories as $child)
    echo '<li class="sub-cat">';
    $cat = $objectManager->create('Magento\Catalog\Model\Category')->load($child->getId()); 

       if ($_imgUrl = $cat->getImageUrl())
        $_imgHtml = '<div class="category-image"><img src="' . $_imgUrl . '" alt="' . $block->escapeHtml($cat->getName()) . '" title="' . $block->escapeHtml($cat->getName()) . '" class="image" /></div>';
        $_imgHtml = $_helper->categoryAttribute($cat, $_imgHtml, 'image');
        /* @escapeNotVerified */ echo $_imgHtml;

echo '</li>'; }
echo '</ul>';
} else {
if (!$block->isContentMode() || $block->isMixedMode()):
echo $block->getProductListHtml();

It's Working Fine for me.

  • You should never use obhectManager in phtml directly. A better sollution is to create s simple custom module and create all the needed functionality in the block itself, and after that call the block in catalog_category_view.xml – Vlad Patru Apr 6 '17 at 20:57
  • Please follow the coding standards of Magento 2. FYI devdocs.magento.com/guides/v2.1/coding-standards/… – Toan Nguyen Aug 14 '17 at 4:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.