Menu Close
    Hire Us Request Quote Reading List Switch to Dark Mode

    Add Custom Image Attribute To Category In Magento 2

    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 InstallData.php file on location vendor\Module\Setup

    <?php
    namespace Vendor\Module\Setup;
    
    use Magento\Eav\Setup\EavSetup;
    use Magento\Eav\Setup\EavSetupFactory;
    use Magento\Framework\Setup\InstallDataInterface;
    use Magento\Framework\Setup\ModuleContextInterface;
    use Magento\Framework\Setup\ModuleDataSetupInterface;
    use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
    
    /**
     * @codeCoverageIgnore
     */
    class InstallData implements InstallDataInterface
    {
        /**
         * EAV setup factory.
         *
         * @var EavSetupFactory
         */
        private $_eavSetupFactory;
        protected $categorySetupFactory;
    
        /**
         * Init.
         *
         * @param EavSetupFactory $eavSetupFactory
         */
        public function __construct(EavSetupFactory $eavSetupFactory, \Magento\Catalog\Setup\CategorySetupFactory $categorySetupFactory)
        {
            $this->_eavSetupFactory = $eavSetupFactory;
            $this->categorySetupFactory = $categorySetupFactory;
        }
    
        /**
         * {@inheritdoc}
         *
         * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
         */
        public function install(
            ModuleDataSetupInterface $setup,
            ModuleContextInterface $context
        ) {
            /** @var EavSetup $eavSetup */
            $eavSetup = $this->_eavSetupFactory->create(['setup' => $setup]);
            $setup = $this->categorySetupFactory->create(['setup' => $setup]);         
            $setup->addAttribute(
                \Magento\Catalog\Model\Category::ENTITY, 'custom_image', [
                    'type' => 'varchar',
                    'label' => 'Custom Image',
                    'input' => 'image',
                    'backend' => 'Magento\Catalog\Model\Category\Attribute\Backend\Image',
                    'required' => false,
                    'sort_order' => 9,
                    'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                    'group' => 'General Information',
                ]
            );
        }
    }
    

     

    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="module/category_image/upload"/>
                        </item>
                    </item>
                </argument>
            </field>
        </fieldset>
    </form>
    
    

    Step:-3

    Add below code in Vendor/Module/etc/di.xml

        <type name="Vendor\Module\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>
        <preference for="Magento\Catalog\Model\Category\DataProvider" type="Vendor\Module\Model\Category\DataProvider" />

    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;
    
    /**
     * Agorae 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 at last step 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;
    	}
    }

    In this way we can add image attribute to category. Thanks…

    . . .

    Comments (20)

    Add Your Comment

  • Samir
    can you provide route.xml code?
  • Mprasad
    Hi
    How to create category multislect attribute with search box
  • Eran Greenwald
    Hello
    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 🙂

    • Huy Tran
      Just try add routes.xml into di/adminhtml.
      Replace module with your routes frontName.
      Your dir will separate with “_”: if your dir is Adminhtml/Category/Imageabc/Upload.php -> category_imageabc/upload
  • Sony
    Hi Rani,
    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.

    • Rani Priya
      Hi Sony,

      Do you have created route for adminhtml? I mean etc/adminhtml/routes.xml file

      • Sony
        Hi yeah, i created the route. Weirdly it works now, do not know what change i made. But it seems working now, and at the end i used the native magento for the backend model ‘Magento\Catalog\Model\Category\Attribute\Backend\Image’, i did not need to create a custom backend model. Thanks ! 😉
  • Akshay
    Can you please explain.
    How to fetch this image in image src in frontend?
  • KW
    How do I install the module?
  • Fanboy
    A really good tutorial – could you add the part about creating the admin route so that this url part works.

  • sumeet
    Thanks,It is working fine.

    Thank you so much.

    • KW
      How do i enable or install the module after following the steps? Thanks!
      • Tom
        Run the “php bin/magento setup:upgrade” command 🙂
  • Orvin Olson
    Not working,
    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

    • Rani Priya
      Hi Orvin,

      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.

  • Daniel Bello
    Hello, good job.
    How can we show this attribute on front end?
    Thanks
    • Rani Priya
      Hi Daniel,

      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

      • Karol
        any chance you write more specific in frontend part ? i cannot make this working ;(
        • Simon
          $this->_storeManager->getStore()->getBaseUrl(UrlInterface::URL_TYPE_MEDIA) . ‘catalog/category/’ . $category->getData(‘custom_image’);
  • Back to Top
    css.php
    Hire Us!
    Brief us about your requirements and we'll get back to you.
    Woo! Hooy!
    We have just recieved your project brief and our expert will contact you shortly.
    Send Again
    Close