Magento – How to create custom tab in product admin section in Magento 2

adminadminhtmlmagento-2.0.7magento2product

I want to create one custom tab in the admin product section for all products and I want to display a custom message. How can I do this?

Best Answer

Update:

I apologize, this answer is working only for version 2.1 +. I won't delete it, perhaps it can helps somebody (who is using the version 2.1 or greater).


Add the modifier in app/code/Vendor/Module/etc/adminhtml/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">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="custom-tab-with-content" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\CustomTab</item>
                    <item name="sortOrder" xsi:type="number">10</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

Create corresponding class Vendor\Module\Ui\DataProvider\Product\Form\Modifier\CustomTab in app/code/Vendor/Module/Ui/DataProvider/Product/Form/Modifier/CustomTab.php:

<?php
namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier;

use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\Container;
use Magento\Ui\Component\Form\Fieldset;

class CustomTab extends AbstractModifier
{

    const CUSTOM_TAB_INDEX = 'custom_tab';
    const CUSTOM_TAB_CONTENT = 'content';

    /**
     * @var \Magento\Catalog\Model\Locator\LocatorInterface
     */
    protected $locator;

    /**
     * @var ArrayManager
     */
    protected $arrayManager;

    /**
     * @var UrlInterface
     */
    protected $urlBuilder;

    /**
     * @var array
     */
    protected $meta = [];

    /**
     * @param LocatorInterface $locator
     * @param ArrayManager $arrayManager
     * @param UrlInterface $urlBuilder
     */
    public function __construct(
        LocatorInterface $locator,
        ArrayManager $arrayManager,
        UrlInterface $urlBuilder
    ) {
        $this->locator = $locator;
        $this->arrayManager = $arrayManager;
        $this->urlBuilder = $urlBuilder;
    }

    public function modifyData(array $data)
    {
        return $data;
    }

    public function modifyMeta(array $meta)
    {
        $this->meta = $meta;
        $this->addCustomTab();

        return $this->meta;
    }

    protected function addCustomTab()
    {
        $this->meta = array_merge_recursive(
            $this->meta,
            [
                static::CUSTOM_TAB_INDEX => $this->getTabConfig(),
            ]
        );
    }

    protected function getTabConfig()
    {
        return [
            'arguments' => [
                'data' => [
                    'config' => [
                        'label' => __('Custom Tab'),
                        'componentType' => Fieldset::NAME,
                        'dataScope' => '',
                        'provider' => static::FORM_NAME . '.product_form_data_source',
                        'ns' => static::FORM_NAME,
                        'collapsible' => true,
                    ],
                ],
            ],
            'children' => [
                static::CUSTOM_TAB_CONTENT => [
                    'arguments' => [
                        'data' => [
                            'config' => [
                                'label' => null,
                                'formElement' => Container::NAME,
                                'componentType' => Container::NAME,
                                'template' => 'ui/form/components/complex',
                                'content' => __('You can write any text here, ') .
                                    ' or html: ' . 
                                    '<h3>Text</h3>' . 
                                    ', or blocks html (using toHtml method).',
                                'sortOrder' => 10,
                            ],
                        ],
                    ],
                    'children' => [],
                ],
            ],
        ];
    }
}

Now you can add your content inside the 'content' section. You can call a block and add its html to the content (using the toHtml method). Change it as you wish.

PS: do not forget to change the vendor name (Vendor) and module name (Module) to corresponding own names.