How to Add “Image” Attribute to a Category in Magento 2

Dec 20, 20161423Mishel Soiko
How to Add “Image” Attribute to a Category in Magento 2

It’s much easier to add “Image” attribute during upgrade or installation process of your module in the following files.

app/code/[ Vendor ]/[ Module ]/Setup/InstallData.php

Or here:

app/code/[ Vendor ]/[ Module ]/Setup/UpgradeData.php

Let me show you how to perform it during upgrade

The second step you have to do is to add this attribute to a category form:

app/code/[ Vendor ]/[ Module ]/view/adminhtml/ui_component/category_form.xml

It would be enough for regular attributes, but not in case of the uploaded “image” attribute. Let’s find out what else we should do to add this attribute properly.

We have already defined the backend model:

And we have defined another URL for the upload:

Probably you are wondering, why do we need another Controller and a new Model? Why can’t we use the default controller and model, that is already defined in the “Image” attribute:

vendor/magento/module-catalog/Model/Category/Attribute/Backend/Image.php

vendor/magento/module-catalog/Controller/Adminhtml/Category/Image/Upload.php

The answer is pretty simple: Magento 2.1.2 still has some versatility issues and code of attribute is placed right in the files. But we have our own attribute, that’s why we should create a new one:

app/code/[ Vendor ]/[ Module ]/Controller/Adminhtml/Category/Thumb/Upload.php

As you can see, the most important thing here is to specify the field in which the uploaded file $this->imageUploader->saveFileToTmpDir(‘image_thumb’) should be searched.

This Controller uploads an image to a temporary directory with the AJAX request. And shows its thumbnail in the admin panel even before the category has been saved.

Further, we need to define a model, which allows us to save the uploaded file, but now during the category saving process.

app/code/[ Vendor ]/[ Module ]/Model/Category/Attribute/Backend/Thumb.php

After the AJAX request, imageUploader returns not only an image itself, but an array with the updated data for the category object. And we should write another string to add the attribute to varchar.

beforeSave – transforms received array to a file name.

afterSave – transfers a file from temporary category to a constant one.

But there is more to come. We haven’t defined those file types, that could be uploaded. And those categories in which should use the uploaded image.

However, we already specified the backend model for these configurations. They are defined in the
app/code/[ Vendor ]/[ Module ]/etc/di.xml

It seems that we finally finished, but after image uploading and category saving admin panel is getting stucked.

Additionally we should define the rewrite for DataProvider file in the di.xml: app/code/[ Vendor ]/[ Module ]/Model/Category/DataProvider.php

And in the end, we have to display this image on the frontend. There is only a file name in the category data. And the following function will help to create a full URL for it.

Check also:

Adding Image Attribute To a Category in Magento 2: Alternative Version



20 Comments

  1. Thanks Mishel. A very useful tutorial.
    It’s actually something I’ve stuck in for a week.
    But I can’t get your code to work either. Would you kindly add a ready-to-use zip of your module code to your article.

  2. All id good, just need to add routes.xml and everything will working fine.
    LOVE U guys…

  3. It doesn’t upload any image file uploader is blank…
    @ankit which code you had written in routes.xml

  4. Thanks Mishel. This is very usefull
    For last method we have to create Helper\Data.php

    [ Vendor ]\[ Module ]\Helper\Data.php

    _storeManager = $storeManager;
    parent::__construct($context);
    }

    public function getCategoryThumbUrl($category) {
    $url = false;
    $image = $category->getImageThumb();
    if ($image) {
    if (is_string($image)) {
    $url = $this->_storeManager->getStore()->getBaseUrl(
    \Magento\Framework\UrlInterface::URL_TYPE_MEDIA
    ) . ‘catalog/category/’ . $image;
    } else {
    throw new \Magento\Framework\Exception\LocalizedException(
    __(‘Something went wrong while getting the image url.’)
    );
    }
    }

    return $url;
    }

    }

  5. This is perfect work on above version of magento 2.2.0 But it’s not working on magento 2.2.0. Is’s display after save category ‘file-uploader.js:74 Uncaught TypeError: value.map is not a function’.

  6. Dear Sanket,

    you are right, this method doesn’t work on Magento 2.2.0 and above. I’ll try to figure out how to fix it and cover this topic in my next articles.

    Regards,
    Mishel

  7. Yes Mishel, it won’t work. And while you’re at it, would you be so kind as to add the routes.xml with which you make it work? For me, the uninitiated and fledgling Magento ( 2 ) developer it’s awfully complicated. Most of the time.

  8. Hello, Jo-Anne! Hope it’ll help.

    <item name=”url” xsi:type=”url” path=”[ module ]/category_thumb/upload”/>

    Thus:

    routes.xml

    <?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=”[ any key ]” frontName=”[ module ]”>
    <module name=”[ Vendor ]_[ Module ]” before=”Magento_Backend” />
    </route>
    </router>
    </config>

  9. Dear Andrew,

    you are right, this method doesn’t work on Magento 2.2.0 and above. I’m going to cover this topic in my next articles. Unfortunately, I don’t have spare time for blogging right now :(

    Regards,
    Mishel

  10. Thx Mishel,
    But if you have solution can you write some words about this, im stack in it about 5 hours :)

  11. Hello, i finded solution, changed the backend_model of attribute to standart magento “Magento\Catalog\Model\Category\Attribute\Backend\Image” and it work, but have an issue with standart field it apear with empty image and when try to save category image field got exception “Method Magento\Ui\TemplateEngine\Xhtml\Result::__toString() must not throw an exception”

  12. When I hit the Upload Buttom a message display in page: ‘A technical problem with the server created an error. Try again to continue what you were doing. If the problem persists, try again later.’

  13. Andrew, thank you for sharing the solution! Hope it solves the problem indeed. I’m pretty sure it helps others as well.

    Diego, unfortunately, I cannot resolve it without getting into details. Please contact our support department in case you need an individual consideration of the matter: store@belvg.com
    We’ll be happy to assist.

Post a new comment

top
BelVG Newsletter
Subscribe to our mailing list and get interesting stuff and updates to your email inbox.
Email *