Magento 2 – Add Magento Widget Button on Product WYSIWYG Editors

magento2widgetwysiwyg

I am missing the "insert widget" button on all WYSIWYG editors on the product edit pages. The magento guys seem to not have thought this through properly.

I found a way to add them to categories: How to add 'Insert Widget' functionality to category WYSIWYG editors in Magento 2 ?

Does anybody know how to add this button to product editors as well? Must be rocket science…

Best Answer

Here’s an example on how to do it for the Description field. You can use it for other WYSIWYG fields in the product edit page (just modify the condition for the IF in step number 2 and add the filter for the additional fields in step number 4).

The cleanest way to do it is by using plugins. You need two plugins, one to insert the button into the form and another to filter the content of the field to inject the widget content.

1) In a custom module, create a di.xml file for the adminhtml area and set a plugin to modify the form data provider:

[Vendor]/[ModuleName]/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">
    <!-- Add "Insert Widget..." button to product description fieldset in the admin -->
    <type name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav">
        <plugin name="[Vendor]_[ModuleName]_Product_Form_Plugin" type="[Vendor]\[ModuleName]\Plugin\Ui\DataProvider\Product\Form\Modifier\Eav"/>
    </type>
</config>

2) Now create the plugin file to insert the button:

[Vendor]\[ModuleName]\Plugin\Ui\DataProvider\Product\Form\Modifier\Eav.php:

<?php
namespace [Vendor]\[ModuleName]\Plugin\Ui\DataProvider\Product\Form\Modifier;

/**
 * Class Eav
 */
class Eav
{
    /**
     * Set 'add_widgets' to true for the description attribute in order to display the "Insert Widget..." button
     *
     * @param \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav $subject
     * @param \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav $result
     * @return \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function afterSetupAttributeMeta(
        \Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Eav $subject,
        $result
    ) {
        if (isset($result['arguments']['data']['config']['code']) &&
            $result['arguments']['data']['config']['code'] == 'description') {
            $result['arguments']['data']['config']['wysiwygConfigData'] = [
                'add_variables' => false,
                'add_widgets' => true,
                'add_directives' => true,
                'use_container' => true,
                'container_class' => 'hor-scroll'
            ];
        }

        return $result;
    }
}

3) Create a di.xml file for the frontend area to set a plugin for the product view helper:

[Vendor]/[ModuleName]/etc/frontend/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">
    <!-- Plugin to filter the product description and process any widget added to it -->
    <type name="Magento\Catalog\Helper\Product\View">
        <plugin name="[Vendor]_[ModuleName]_State_Selector_Plugin" type="[Vendor]\[ModuleName]\Plugin\Helper\Product\View"/>
    </type>
</config>

4) And finally, create the plugin file in the following path:

[Vendor]/[ModuleName]/Plugin/Helper/Product/View.php:

<?php
namespace [Vendor]\[ModuleName]\Plugin\Helper\Product;

use Magento\Cms\Model\Template\FilterProvider;

/**
 * Class View
 */
class View
{
    /**
     * @var FilterProvider
     */
    private $_filterProvider;

    /**
     * Constructor.
     *
     * @param FilterProvider $filterProvider
     */
    public function __construct(
        FilterProvider $filterProvider
    ) {
        $this->_filterProvider = $filterProvider;
    }

    /**
     * Init layout for viewing product page
     *
     * @param \Magento\Catalog\Helper\Product\View $subject
     * @param \Magento\Catalog\Helper\Product\View $result
     * @param \Magento\Framework\View\Result\Page $resultPage
     * @param \Magento\Catalog\Model\Product $product
     * @param null|\Magento\Framework\DataObject $params
     * @return \[Vendor]\[ModuleName]\Plugin\Helper\Product\View
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function afterInitProductLayout(
        \Magento\Catalog\Helper\Product\View $subject,
        $result,
        $resultPage,
        $product,
        $params
    ) {
        // filter product description to process widgets
        $description = $product->getResource()->getAttribute('description')->getFrontend()->getValue($product);
        $filteredDescription = $this->_filterProvider->getPageFilter()->filter($description);
        $product->setDescription($filteredDescription);

        return $this;
    }
}
Related Topic