Magento2 | PWA | GraphQL

How to add extra category description (textarea category EAV attribute) in the product listing page - Magento2


In this tutorial, you will learn how to add an extra category description on the product list page by adding a textarea as a category EAV attribute.

Let's start it by creating a custom module.

Find the complete module at Magelearn_CustomInfo

Create a folder in app/code/Magelearn/CustomInfo

Step 1: Create module registration file

Add registration.php file in it:
<?php

declare(strict_types=1);

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::MODULE,
    'Magelearn_CustomInfo',
    __DIR__
);
Add composer.json file in it:
{
    "name": "magelearn/module-custom-info",
    "description": "Adds a store-scoped bottom category description and displays it on the category product listing page.",
    "type": "magento2-module",
    "license": "OSL-3.0",
    "authors": [
        {
            "name": "Vijay Rami",
            "email": "vijaymrami@gmail.com"
        }
    ],
    "require": {
        "php": ">=8.1"
    },
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magelearn\\CustomInfo\\": ""
        }
    }
}
Add etc/module.xml file in it:
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Magelearn_CustomInfo"/>
</config>

Step 2. Create the Bottom Description field in the backend.

Create AddBottomDescriptionAttribute.php inside Setup/Patch/Data/AddBottomDescriptionAttribute.php
<?php

declare(strict_types=1);

namespace Magelearn\CustomInfo\Setup\Patch\Data;

use Magento\Catalog\Model\Category;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface;
use Magento\Eav\Setup\EavSetup;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

class AddBottomDescriptionAttribute implements DataPatchInterface
{
    private const ATTRIBUTE_CODE = 'bottom_description';

    public function __construct(
        private readonly ModuleDataSetupInterface $moduleDataSetup,
        private readonly CategorySetupFactory $categorySetupFactory
    ) {
    }

    public function apply(): self
    {
        $this->moduleDataSetup->getConnection()->startSetup();

        try {
            /** @var EavSetup $categorySetup */
            $categorySetup = $this->categorySetupFactory->create([
                'setup' => $this->moduleDataSetup,
            ]);

            if (!$categorySetup->getAttributeId(Category::ENTITY, self::ATTRIBUTE_CODE)) {
                $categorySetup->addAttribute(
                    Category::ENTITY,
                    self::ATTRIBUTE_CODE,
                    [
                        'type' => 'text',
                        'label' => 'Bottom Description',
                        'input' => 'textarea',
                        'required' => false,
                        'sort_order' => 9,
                        'wysiwyg_enabled' => true,
                        'is_html_allowed_on_front' => true,
                        'global' => ScopedAttributeInterface::SCOPE_STORE,
                        'group' => 'General Information',
                    ]
                );
            }
        } finally {
            $this->moduleDataSetup->getConnection()->endSetup();
        }

        return $this;
    }

    public function revert(): void
    {
        $this->moduleDataSetup->getConnection()->startSetup();

        try {
            /** @var EavSetup $categorySetup */
            $categorySetup = $this->categorySetupFactory->create([
                'setup' => $this->moduleDataSetup,
            ]);

            if ($categorySetup->getAttributeId(Category::ENTITY, self::ATTRIBUTE_CODE)) {
                $categorySetup->removeAttribute(Category::ENTITY, self::ATTRIBUTE_CODE);
            }
        } finally {
            $this->moduleDataSetup->getConnection()->endSetup();
        }
    }

    public static function getDependencies(): array
    {
        return [];
    }

    public function getAliases(): array
    {
        return [];
    }
}
This code snippet below will add a visual Bottom Description attribute for the categories in the admin panel, which includes WYSIWYG editor enabled.

Create category_form.xml inside Magelearn/CustomInfo/view/adminhtml/ui_component
<?xml version="1.0"?>
<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="bottom_description" sortOrder="60" formElement="wysiwyg">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="wysiwygConfigData" xsi:type="array">
                        <item name="height" xsi:type="string">100px</item>
                        <item name="add_variables" xsi:type="boolean">false</item>
                        <item name="add_widgets" xsi:type="boolean">false</item>
                        <item name="add_images" xsi:type="boolean">true</item>
                        <item name="add_directives" xsi:type="boolean">true</item>
                    </item>
                    <item name="source" xsi:type="string">category</item>
                </item>
            </argument>
            <settings>
                <label translate="true">Bottom Description</label>
                <dataScope>bottom_description</dataScope>
            </settings>
            <formElements>
                <wysiwyg class="Magento\Catalog\Ui\Component\Category\Form\Element\Wysiwyg">
                    <settings>
                        <rows>8</rows>
                        <wysiwyg>true</wysiwyg>
                    </settings>
                </wysiwyg>
            </formElements>
        </field>
    </fieldset>
</form>
After adding those files above you should see the field below category description.


Step 3. Make visible in the product listing page.

Here, we will push the texts we added in the backend. First, you need to create a phtml file which contains the attribute text. Then you can put the text to bottom in the category page.

Create catalog_category_view.xml inside Magelearn/CustomInfo/view/frontend/layout
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block
                class="Magelearn\CustomInfo\Block\Info"
                name="magelearn.custominfo.bottom.description"
                template="Magelearn_CustomInfo::product/list/bottom_description.phtml"
                before="-"/>
        </referenceContainer>
    </body>
</page>
Here we add our custom block and before="-" will add this bottom description content before the category content. 

Create Info.php inside Magelearn/CustomInfo/Block
<?php

declare(strict_types=1);

namespace Magelearn\CustomInfo\Block;

use Magento\Catalog\Model\Category;
use Magento\Catalog\Helper\Output as CatalogOutput;
use Magento\Catalog\Model\Layer\Resolver as LayerResolver;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;

class Info extends Template
{
    private ?Category $category = null;

    public function __construct(
        Context $context,
        private readonly LayerResolver $layerResolver,
        private readonly CatalogOutput $catalogOutput,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    public function getBottomDescriptionHtml(): string
    {
        $category = $this->getCurrentCategory();
        $description = (string) $category->getData('bottom_description');

        if ($description === '') {
            return '';
        }

        return (string) $this->catalogOutput->categoryAttribute(
            $category,
            $description,
            'bottom_description'
        );
    }

    /**
     * Retrieve the current category from the catalog layer.
     *
     * @throws LocalizedException If the current category cannot be resolved.
     */
    public function getCurrentCategory(): Category
    {
        if ($this->category === null) {
            $category = $this->layerResolver->get()->getCurrentCategory();

            if (!$category->getId()) {
                throw new LocalizedException(
                    __('Category object could not be found.')
                );
            }

            $this->category = $category;
        }

        return $this->category;
    }
}
At last, Create bottom_description.phtml inside Magelearn/CustomInfo/view/frontend/templates/product/list
<?php
/** @var \Magelearn\CustomInfo\Block\Info $block */
$bottomDescription = $block->getBottomDescriptionHtml();

if ($bottomDescription):
    ?>
    <div class="category-bottom-description">
        <?= /* @noEscape */ $bottomDescription ?>
    </div>
<?php endif; ?>
After doing all the steps above. Enable the module, generate classes and refresh the cache. If everything was well, now you should see something like this.




0 Comments On "How to add extra category description (textarea category EAV attribute) in the product listing page - Magento2"

Back To Top