Skip to content

Create Page Builder Widget

Hai Huynh edited this page Jun 23, 2023 · 1 revision

1. Register Entry Point In Module

1.1 Create the module entry point

In your module, Goomento will only rely on your entry point and nowhere else

EntryPoint must extend from Goomento\PageBuilder\BuilderRegister

Eg:

namespace Company\Module;

use Goomento\PageBuilder\BuilderRegister;

class EntryPoint extends BuilderRegister
{
}

1.2 Inject the entry point to process by Page Builder

In your <Module_Folder>/etc/di.xml add

<type name="Goomento\PageBuilder\PageBuilder">
    <arguments>
        <argument name="components" xsi:type="array">
            <item name="component-name" xsi:type="string">Path\To\EntryPoint</item>
        </argument>
    </arguments>
</type>

Note:

  • component-name: must be unique
  • Path\To\EntryPoint: EntryPoint which is created step above

Eg:

<type name="Goomento\PageBuilder\PageBuilder">
    <arguments>
        <argument name="components" xsi:type="array">
            <item name="company-module-builder" xsi:type="string">Company\Module\EntryPoint</item>
        </argument>
    </arguments>
</type>

2. Create Very First Buildable Widget

2.1 Create your widget class

Create <Module_Folder>/Builder/Widgets folder to stores all the widget

WidgetClass must extend from Goomento\PageBuilder\Builder\Base\AbstractWidget

namespace Company\Module\Builder\Widgets;

use Goomento\PageBuilder\Builder\Base\AbstractWidget;
use Goomento\PageBuilder\Builder\Managers\Controls;
use Magento\Framework\Phrase;

class HelloWorld extends AbstractWidget
{
    /**
     * Unique name of widget
     */
    const NAME = 'hello-world';

    /**
     * Template which present for HTML output of widget
     *
     * @var string
     */
    protected $template = 'Company_Module::widgets/hello_world.phtml';

    /**
     * Name of widget, It will display at Editor
     *
     * @return Phrase|string
     */
    public function getTitle()
    {
        return __('Hello World');
    }

    /**
     * Icon of widget, It will display in Page Builder Editor
     
     * @link https://fontawesome.com/
     * @return string
     */
    public function getIcon()
    {
        return 'fas fa-hand-peace';
    }

    /**
     * Keywords for search of widget in search bar at Editor
     *
     * @return string[]
     */
    public function getKeywords()
    {
        return [ 'hello world' ];
    }

    /**
     * Used to add new controls to widget. For example, external
     * developers use this method to register controls in a widget.
     *
     * @return void
     */
    protected function registerControls()
    {
        $this->startControlsSection(
            'section_hello_world_info',
            [
                'label' => __('Information'),
            ]
        );

        $this->addControl(
            'hello-world-name',
            [
                'label' => __('Your Name Is'),
                'type' => Controls::TEXT,
                'default' => '',
                'placeholder' => __('Eg: John'),
            ]
        );

        $this->endControlsSection();
    }
}

Other samples can be found here Goomento\PageBuilder\Builder\Widgets

2.2 Add template .phtml

Create file <Module_Folder>/view/frontend/widgets/<template_name>.phtml which defined at WidgetClass::$template

Eg:

use Company\Module\Builder\Widgets\HelloWorld;
use Goomento\PageBuilder\Block\View\Element\Widget;
use Goomento\PageBuilder\Helper\EscaperHelper;

/**
 * @var Widget $block
 * @var HelloWorld $widget
 * @var array $settings
 */

$widget = $block->getWidget();
$settings = $block->getSettingsForDisplay();

/**
 * `hello-world-name` is the key, which is set in the `registerControls`
 * @see Company\Module\Builder\Widgets\HelloWorld::registerControls()
 */
if (!empty($settings['hello-world-name'])) : ?>
    <p class="hello-world"><?= __('Hello World! My name is %1', $block->escapeHtml($settings['hello-world-name'])) ?></p>
<?php endif;

2.3 Add New Widget To Editor

Overwrite method Company\Module\EntryPoint::registerWidgets() then add WidgetClass

Eg:

namespace Company\Module;

class EntryPoint extends BuilderRegister
{
    /**
     * Add your widgets to be used here
     *
     * @see Widgets::registerWidgetType()
     */
    public function registerWidgets(Widgets $widgetsManager)
    {
        $widgetsManager->registerWidgetType(
            \Company\Module\Builder\Widgets\HelloWorld::class
        );
    }
}

3. Add JS/CSS

3.1 Register CSS

Create the CSS file <Module_Folder>/view/frontend/web/css/hello-world.less

Eg:

/**
 * Should wrap widget style in wrapper
 * Wrapper format .gmt-widget-<unique-name-of-widget>
 */
.gmt-widget-hello-world {
    .hello-world {
        color: red; // change color of text to red
    }
}

Overwrite method Company\Module\EntryPoint::registerStyles() then add CSS path

Eg:

namespace Company\Module;

class EntryPoint extends BuilderRegister
{
    /**
     * Add to queue your css files, that can be used by widget or theme later
     *
     * @return void
     */
    public function registerStyles()
    {
        ThemeHelper::registerStyle(
            'hello-world-css',
            'Company_Module::css/hello-world.css'
        );
    }
}

3.2 Register JS

Create the JS file <Module_Folder>/view/frontend/web/hello-world.js, and wrap your function in case of co-work with widget

define([
    'jquery',
    'goomento-widget-base',
], function ($) {
    'use strict';

    /**
     * Alert widget
     */
    $.widget('goomento.helloWorld', $.goomento.base, {
        options: {
            colors: ['red', 'green', 'yellow', 'black']
        },
        /**
         * On initializing widget
         */
        _initWidget: function () {
           // Custom function
           setInterval(() => {
                // Get random color from `defaultConfig`
                let color = this.options.colors[Math.random() * args.colors.length | 0];

                // Changing color
                this.$element.find('.hello-world').css('color', color);
            }, 1000);
        }
    });

    return $.goomento.helloWorld;
});

Overwrite method Company\Module\EntryPoint::registerScripts() then add JS paths

Eg:

namespace Company\Module;

use Goomento\PageBuilder\Helper\ThemeHelper;

class EntryPoint extends BuilderRegister
{
    /**
     * Add to queue your js files, that can be used by widget
     *
     * @return void
     */
    public function registerScripts()
    {
        ThemeHelper::registerScript(
            'hello-world-js',
            'Company_Module/js/hello-world'
        );
    }

}

3.3 Add CSS/JS to Widget for use as dependencies

In case of Widget being used, the CSS or JS will be added automatically into storefront . To do that, should add CSS or JS to widget as a dependency.

Eg:

namespace Company\Module\Builder\Widgets;

use Goomento\PageBuilder\Helper\ThemeHelper;

class HelloWorld extends AbstractWidget
{
    
    /**
     * Get style dependencies.
     *
     * Retrieve the list of style dependencies the element requires.
     *
     * @see \Company\Module\EntryPoint::registerStyles()
     * @return array
     */
    public function getStyleDepends()
    {
        return ['hello-world-css'];
    }

    /**
     * Get script dependencies.
     *
     * Retrieve the list of script dependencies the element requires.
     *
     *
     * @return array Element scripts dependencies.
     */
    public function getScriptDepends()
    {
        return ['hello-world-js'];
    }
}