Adding new category attributes in Magento 2

In this post, we aim to share our expertise on creating a category attribute in Magento 2. As you may have noticed, we need to change (add or customize) category attributes from time to time. We have done it many times for Magento 1 and now we faced the same task in Magento 2. This process is very similar for both Magento versions, however there are some differences. So let’s check how we can do it step by step.

To meet our requirements, we must create a new module, which we’ll call ‘Category Attribute’. Then we can use an install script to add a new category attribute.

To create new module in Magento 2 we need the following files:

app/code/Atwix/CategoryAttribute/etc/module.xml
app/code/Atwix/CategoryAttribute/registration.php
app/code/Atwix/CategoryAttribute/composer.json
<?xml version="1.0"?>
<!-- file: app/code/Atwix/CategoryAttribute/etc/module.xml -->

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Atwix_CategoryAttribute" setup_version="1.0.0" />
</config>
<?php
/* file: app/code/Atwix/CategoryAttribute/registration.php  */
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Atwix_CategoryAttribute',
    __DIR__
);
{
  "name": "atwix/categoryattribute",
  "description": "N/A",
  "require": {
    "php": "~5.5.0|~5.6.0|~7.0.0"
  },
  "type": "magento2-module",
  "version": "1.0.0",
  "license": [
    "OSL-3.0",
    "AFL-3.0"
  ],
  "autoload": {
    "files": [ "registration.php" ],
    "psr-4": {
      "Atwix\\CategoryAttribute\\": ""
    }
  }
}

Note: you can find more information about module components here.

All the main changes will be added to the install script, so in order to add a new category attribute, we need to create a script file for our module:

<?php
/* file: app/code/Atwix/CategoryAttribute/Setup/InstallData.php */

namespace Atwix\CategoryAttribute\Setup;

use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Catalog\Model\Category;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;

/**
 * @codeCoverageIgnore
 */
class InstallData implements InstallDataInterface
{
    /**
     * @var EavSetupFactory
     */
    private $eavSetupFactory;

    /**
     *
     * @param EavSetupFactory $eavSetupFactory
     */
    public function __construct(EavSetupFactory $eavSetupFactory)
    {
        $this->eavSetupFactory = $eavSetupFactory;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);
        $eavSetup->addAttribute(
            Category::ENTITY,
            'custom_attribute',
            [
                'type' => 'varchar',
                'label' => 'Custom attribute',
                'input' => 'text',
                'required' => false,
                'sort_order' => 100,
                'global' => ScopedAttributeInterface::SCOPE_STORE,
                'group' => 'General Information',
            ]
        );
    }
}

As you may know, in the latest Magento versions, the category form for the admin panel is created via configuration file (app/code/Magento/Catalog/view/adminhtml/ui_component/category_form.xml or vendor/magento/module-catalog/view/adminhtml/ui_component/category_form.xml), so we need to create the same configuration file for our module and add our attribute to the category form. Please, see the example below:

<?xml version="1.0" encoding="UTF-8"?>
<!-- file: app/code/Atwix/CategoryAttribute/view/adminhtml/ui_component/category_form.xml -->

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="custom_content">
        <argument name="data" xsi:type="array">
            <item name="config" xsi:type="array">
                <item name="label" xsi:type="string" translate="true">Custom Content</item>
                <item name="collapsible" xsi:type="boolean">true</item>
                <item name="sortOrder" xsi:type="number">100</item>
            </item>
        </argument>
        <field name="custom_attribute">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="sortOrder" xsi:type="number">10</item>
                    <item name="dataType" xsi:type="string">string</item>
                    <item name="formElement" xsi:type="string">input</item>
                    <item name="label" xsi:type="string" translate="true">Custom Attribute</item>
                    <item name="required" xsi:type="boolean">false</item>
                </item>
            </argument>
        </field>
    </fieldset>
</form>

After all these changes we should enable our module, so we need to run the following commands:

./bin/magento cache:flush
./bin/magento module:enable Atwix_CategoryAttribute
./bin/magento setup:upgrade

Finally, we can check the result in the admin panel:

custom attribute example

If we need to change settings for the created category attribute, add a new one, change or remove other attributes in future – we can use an install data script. Moreover, a lot of examples on how to work with EAV attributes can be found in Magento core modules.

We believe this post will be useful for you during your first steps when working with category attributes. Feel free to share your thoughts and questions in comments below.

Read more: