Add Custom Image Attribute To Category In Magento 2 – Here I’m going to explain you how to add custom image attribute to category.
Step:-1
Create a AddCustomImageAttribute.php file on location vendor\Module\Setup\Patch\Data
<?php namespace Vendor\Module\Setup\Patch\Data; use Magento\Customer\Setup\CustomerSetupFactory; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Catalog\Model\Category; class AddCustomImageAttribute implements DataPatchInterface { public const ATTRIBUTE_CODE = 'custom_image'; /** * @var ModuleDataSetupInterface */ private $moduleDataSetup; /** * @var CustomerSetupFactory */ private $customerSetupFactory; /** * @param ModuleDataSetupInterface $moduleDataSetup * @param CustomerSetupFactory $customerSetupFactory */ public function __construct( ModuleDataSetupInterface $moduleDataSetup, CustomerSetupFactory $customerSetupFactory ) { $this->moduleDataSetup = $moduleDataSetup; $this->customerSetupFactory = $customerSetupFactory; } /** * @inheritdoc */ public function apply() { $customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]); $customerSetup->addAttribute(Category::ENTITY, self::ATTRIBUTE_CODE, [ 'type' => 'varchar', 'label' => 'Custom Image', 'input' => 'image', 'backend' => \Magento\Catalog\Model\Category\Attribute\Backend\Image::class, 'required' => false, 'sort_order' => 9, 'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE, 'group' => 'General Information', ]); } /** * @inheritdoc */ public static function getDependencies() { return []; } /** * @inheritdoc */ public function getAliases() { return []; } }
Step:-2
Create a category_form.xml file on location vendor\Module\view\adminhtml\ui_component
<?xml version="1.0" encoding="UTF-8"?> <form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> <fieldset name="content"> <field name="custom_image"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="dataType" xsi:type="string">string</item> <item name="source" xsi:type="string">category</item> <item name="label" xsi:type="string" translate="true">Custom Image</item> <item name="visible" xsi:type="boolean">true</item> <item name="formElement" xsi:type="string">fileUploader</item> <item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item> <item name="previewTmpl" xsi:type="string">Magento_Catalog/image-preview</item> <item name="required" xsi:type="boolean">false</item> <item name="sortOrder" xsi:type="number">40</item> <item name="uploaderConfig" xsi:type="array"> <item name="url" xsi:type="url" path="front_name/category_image/upload"/> </item> </item> </argument> </field> </fieldset> </form>
Step:-3
Add below code in Vendor/Module/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\Model\Category\DataProvider" type="Webkul\ProductFileAttribute\Model\Category\DataProvider" /> <type name="Webkul\ProductFileAttribute\Controller\Adminhtml\Category\Image\Upload"> <arguments> <argument name="imageUploader" xsi:type="object">Magento\Catalog\CategoryImageUpload</argument> </arguments> </type> <virtualType name="Magento\Catalog\CategoryImageUpload" type="Magento\Catalog\Model\ImageUploader"> <arguments> <argument name="baseTmpPath" xsi:type="string">catalog/tmp/category</argument> <argument name="basePath" xsi:type="string">catalog/category</argument> <argument name="allowedExtensions" xsi:type="array"> <item name="jpg" xsi:type="string">jpg</item> <item name="jpeg" xsi:type="string">jpeg</item> <item name="gif" xsi:type="string">gif</item> <item name="png" xsi:type="string">png</item> </argument> </arguments> </virtualType> </config>
Step:-4
Create Upload.php file on location Vendor/Module/Controller/Adminhtml/Category/Image
<?php namespace Vendor\Module\Controller\Adminhtml\Category\Image; use Magento\Framework\Controller\ResultFactory; /** * Adminhtml Category Image Upload Controller */ class Upload extends \Magento\Backend\App\Action { /** * Image uploader * * @var \Magento\Catalog\Model\ImageUploader */ protected $imageUploader; /** * Uploader factory * * @var \Magento\MediaStorage\Model\File\UploaderFactory */ private $uploaderFactory; /** * Media directory object (writable). * * @var \Magento\Framework\Filesystem\Directory\WriteInterface */ protected $mediaDirectory; /** * Store manager * * @var \Magento\Store\Model\StoreManagerInterface */ protected $storeManager; /** * Core file storage database * * @var \Magento\MediaStorage\Helper\File\Storage\Database */ protected $coreFileStorageDatabase; /** * @var \Psr\Log\LoggerInterface */ protected $logger; /** * Upload constructor. * * @param \Magento\Backend\App\Action\Context $context * @param \Magento\Catalog\Model\ImageUploader $imageUploader */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\Catalog\Model\ImageUploader $imageUploader, \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory, \Magento\Framework\Filesystem $filesystem, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\MediaStorage\Helper\File\Storage\Database $coreFileStorageDatabase, \Psr\Log\LoggerInterface $logger ) { parent::__construct($context); $this->imageUploader = $imageUploader; $this->uploaderFactory = $uploaderFactory; $this->mediaDirectory = $filesystem->getDirectoryWrite(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); $this->storeManager = $storeManager; $this->coreFileStorageDatabase = $coreFileStorageDatabase; $this->logger = $logger; } /** * Check admin permissions for this controller * * @return boolean */ protected function _isAllowed() { return $this->_authorization->isAllowed('Vendor_Module::category'); } /** * Upload file controller action * * @return \Magento\Framework\Controller\ResultInterface */ public function execute() { try { $result = $this->imageUploader->saveFileToTmpDir('custom_image'); $result['cookie'] = [ 'name' => $this->_getSession()->getName(), 'value' => $this->_getSession()->getSessionId(), 'lifetime' => $this->_getSession()->getCookieLifetime(), 'path' => $this->_getSession()->getCookiePath(), 'domain' => $this->_getSession()->getCookieDomain(), ]; } catch (\Exception $e) { $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()]; } return $this->resultFactory->create(ResultFactory::TYPE_JSON)->setData($result); } }
Step:-5
Then create DataProvider.php file on location Vendor\Module\Model\Category
<?php namespace Vendor\Module\Model\Category; class DataProvider extends \Magento\Catalog\Model\Category\DataProvider { protected function getFieldsMap() { $fields = parent::getFieldsMap(); $fields['content'][] = 'custom_image'; // custom image field return $fields; } }
Step:-6
Then at last create routes.xml on location Vendor\Module\etc\adminhtml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="admin"> <route id="route_id" frontName="front_name"> <module name="Vendor_Module"/> </route> </router> </config>

In this way we can add image attribute to category. Thanks…
20 comments
How to create category multislect attribute with search box
Thank you for this post, it helped me a lot.
When i upload an image i get 404 on this url:
Site_Admin_Url/module/category_image/upload/key
How can i fix this.
Thanks 🙂
Replace module with your routes frontName.
Your dir will separate with “_”: if your dir is Adminhtml/Category/Imageabc/Upload.php -> category_imageabc/upload
What was the Magento version when you did this tutorial ?
I followed your steps on a Magento version 2.3 , but no luck.
Actually all is working fine, except that the image is not saved.
I think that we need to specify a custom backend source image which extends the native.
Regards.
Do you have created route for adminhtml? I mean etc/adminhtml/routes.xml file
How to fetch this image in image src in frontend?
Thank you so much.
why you always not fill the full information ?
getting this error – customcategorybannerimage/category_image/upload/key/a26831343598a8889c6c149f2976140ece250c41d2d4927c90117fd5a74bfab0/?isAjax=true
and we know you not accept our comment
Hope it’s working fine at your end as well.
In case if you will face any other issue then comment below we will surely help you.
How can we show this attribute on front end?
Thanks
Please follow below steps in order to get image url at frontend.
careate instance of class Magento\Catalog\Model\CategoryRepository
then get category model by calling get method like
$category = $categoryRepository->get($categoryId, $storeId);
$imageUrl = “magento_media_url_path”.”catalog/category/”.$category->getCustomImage();
And then you can use this $imageUrl in your custom category page or as per your design.
Thanks