Magento – How to add ‘Insert Widget’ functionality to category WYSIWYG editors in Magento 2

categorymagento2widget

Regarding Magento 2,

I want to add 'Insert Widget' button on category WYSIWYG editor. For more information please find attached screen shots.

  1. cms_insert_widget.png — I want functionality like this.
    enter image description here

  2. category_description_widget.png — Where i want this functionality.

enter image description here

Best Answer

In case anyone is wondering how to do this in Magento 2.1.x (and probably 2.2+ as well). Here's how:

Create your own custom module and add view/adminhtml/ui_component/category_form.xml with (at least) the following code in it:

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <!--
        Add widget and variable buttons:
    -->
    <fieldset name="content">
        <field name="description">
            <argument name="data" xsi:type="array">
                <item name="config" xsi:type="array">
                    <item name="wysiwygConfigData" xsi:type="array">
                        <item name="settings" xsi:type="array">
                            <item name="theme_advanced_buttons1" xsi:type="string">magentovariable,magentowidget,|,bold,italic,|,justifyleft,justifycenter,justifyright,|,fontselect,fontsizeselect,|,forecolor,backcolor,|,link,unlink,image,|,bullist,numlist,|,code</item>
                        </item>
                        <item name="add_variables" xsi:type="boolean">true</item>
                        <item name="add_widgets" xsi:type="boolean">true</item>
                    </item>
                </item>
            </argument>
        </field>
    </fieldset>
</form>

This will add the variable and widget buttons to the description-field when you're editing a category. But the widgets/variables need to be rendered as well on the frontend, otherwise you would just see the widget tags appear as text on the frontend (this was the question asked by anujeet).

To do this, add a plugin to your etc/di.xml (or etc/frontend/di.xml) with the following:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <!--
        Plugin to render widgets in category description:
    -->
    <type name="Magento\Catalog\Model\Template\Filter">
        <plugin name="render_widgets" type="Vendor\Module\Plugin\Magento\Catalog\Model\Template\Filter" />
    </type>
</config>

And in Vendor\Module\Plugin\Magento\Catalog\Model\Template\Filter.php put:

use Magento\Cms\Model\Template\FilterProvider;

/**
 * Class Filter
 */
class Filter
{
    /**
     * @var FilterProvider
     */
    protected $filterProvider;

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

    /**
     * @param \Magento\Catalog\Model\Template\Filter $subject
     * @param string $returnValue
     * @return string
     */
    public function afterFilter(\Magento\Catalog\Model\Template\Filter $subject, string $returnValue)
    {
        return $this->filterProvider
            ->getBlockFilter()
            ->filter($returnValue);
    }
}

That's it! Everything should work now.