Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save aleron75/ddd03576bf28bde69652d858962bbb77 to your computer and use it in GitHub Desktop.

Select an option

Save aleron75/ddd03576bf28bde69652d858962bbb77 to your computer and use it in GitHub Desktop.
Mage-OS Page Builder Widget component explanation

Why we need this module and that kind of feature?

Mage-OS PageBuilder Widget module (part of the Mage-OS release since 2.0 version) allows the user to specify CMS widgets and the related configurations inside a dedicated PageBuilder component named "CMS Widget". As for all PageBuilder components, this component is draggable and can be placed inside other components. The main feature of this module is the ability to configure widgets and see a preview on the PageBuilder.

In terms of developer experience, this module is an enhancement that eliminates the need to develop PageBuilder dedicated components and understand all the stuff behind it (UI Components, PageBuilder inheritance logic, preview vs actual frontend representation).

The main goal of the module is to simplify the development, customization and usage of PageBuilder UI components, relying entirely on CMS widgets (that are pretty easy to use).

How it works

The module makes the preview management transparent to the developer. All we need to do to use our custom CMS widgets inside PageBuilder is change the xsi:noNamespaceSchemaLocation inside the widget.xml file or create a new module that requires the module that declares these widgets inside its sequence node of the module.xml file.

Here it is an example with a CMS widget named my_awesome_slideshow inside Vendor_Widget module that we want to use on PageBuilder.

  1. Create a new module called, for example, Vendor_WidgetPreview with the following files inside it:
--- etc/
------ module.xml
------ widget.xml
  1. Specify the dependencies inside the module.xml file:
<?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="Vendor_WidgetPreview">
        <sequence>
            <module name="MageOS_PageBuilderWidget"/>
            <module name="Vendor_Widget"/>
        </sequence>
    </module>
</config>
  1. Specify the correct schema location in the widget.xml file and customize it to make the preview work:
<?xml version="1.0" encoding="UTF-8"?>

<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:MageOS_PageBuilderWidget:etc/widget.xsd">
  <widget id="my_awesome_slideshow">
  ...
  </widget>
</widgets>

From now on, we will be able to have the preview with additional tools.

previewTemplates instructions

The first thing is to specify which phtml will be used to generate the preview. Inside the Vendor_WidgetPreview in the widget.xml file, specify the templates:

<widget id="my_awesome_slideshow">
    <previewTemplates>
        <previewTemplate name="my_frontend_path/default.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/default.phtml</previewTemplate>
        <previewTemplate name="my_advanced_frontend_path/advanced.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/advanced.phtml</previewTemplate>
    </previewTemplates>
</widget>

We can have multiple templates assigned to our widget, so we need to declare the dedicated preview template for each path. For example, inside our widget, we should set something like the following inside one of the parameter nodes:

...
<parameter name="template" type="select" visible="true" translate="label">
    <label>Template</label>
    <option name="default" value="my_frontend_path/default.phtml" selected="true" translate="label">
        <label>Default template</label>
    </option>
    <option name="advanced" value="my_advanced_frontend_path/advanced.phtml" translate="label">
        <label>Advanced Template</label>
    </option>
</parameter>
...

It's important to specify the correct value for the name attribute in the previewTemplate tag using the same string used in the value attribute of the option tag in the main widget.xml file.

The preview phtml files must be placed inside the adminhtml folder of the module, like shown below:

--- etc/
------ module.xml
------ widget.xml
--- view/
------ adminhtml/
--------- my_frontend_path/
------------ default.phtml
--------- my_advanced_frontend_path
------------ advanced.phtml

If you're building a new widget, we recommend placing the template phtml file inside base folder, so it can be used both for the preview and the main frontend template.

Normally, there aren't differences between the phtml files; rather, it's more common to have different Block classes associated.

previewBlock instructions

<widget id="my_awesome_slideshow">
    <previewTemplates>
      <previewTemplate name="my_frontend_path/default.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/default.phtml</previewTemplate>
        <previewTemplate name="my_advanced_frontend_path/advanced.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/advanced.phtml</previewTemplate>
    </previewTemplates>
    <previewBlock>Vendor\WidgetPreview\Block\Adminhtml\Widget\Preview\MyPreviewBlock</previewBlock>
    ...
</widget>

As described before, the Block class used for the frontend may differ from the class used for the adminhtml preview, mainly because some dependencies can't be used on the adminhtml area.

Thus, the above examples show how to specify a different Block class.

previewBlockArguments instructions

If we're extending a module that already specifies the preview for PageBuilder and we need to make customizations and introduce additional logic, we need a more maintainable approach.

For example, as for the viewModel frontend pattern, we can use similar instructions on widgets.

<widget id="my_awesome_slideshow">
    <previewBlockArguments>
        <argument name="viewModel" 
          xsi:type="object">Vendor\WidgetPreview\ViewModel\Adminhtml\Widget\Preview\MyViewModelPreviewBlock</argument>
    </previewBlockArguments>
</widget>

This way, we're able to use that viewModel inside the preview phtml template:

<?php
/**  @var Vendor\WidgetPreview\ViewModel\Adminhtml\Widget\Preview\MyViewModelPreviewBlock $viewModelPreview */
$viewModelPreview = $block->getData('viewModel');
...

previewCss instructions

For every preview, this module allows us to specify a dedicated CSS file for custom styles.

Keep in mind that these files are included in each widget instance preview on PageBuilder.

Be sure to use specific enough CSS selectors to avoid conflicts with other components and the page outside the PageBuilder stage.

<widget id="my_awesome_slideshow">
    <previewTemplates>
      <previewTemplate name="my_frontend_path/default.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/default.phtml</previewTemplate>
        <previewTemplate name="my_advanced_frontend_path/advanced.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/advanced.phtml</previewTemplate>
    </previewTemplates>
    ...
    <previewCss>Vendor_WidgetPreview::css/widget/preview/style_updates.css</previewCss>
    ...
</widget>

Attention: Remember to place the following PHP snippet inside your phtml preview file for CSS inclusion.

<?= $block->getChildHtml("previewAssets"); ?>

previewJs instructions

For JS inclusion, we can do similarly to what we do for PreviewCss.

For every preview, this module allows specifying a dedicated JS file.

Inside this file, you can add JS actions and triggers to the preview.

Remember that mouse actions are not triggered on widgets preview elements, so this JS is useful for animations only (e.g., sliders scroll, etc.)

<widget id="my_awesome_slideshow">
    <previewTemplates>
      <previewTemplate name="my_frontend_path/default.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/default.phtml</previewTemplate>
        <previewTemplate name="my_advanced_frontend_path/advanced.phtml" 
          xsi:type="string">Vendor_WidgetPreview::preview/advanced.phtml</previewTemplate>
    </previewTemplates>
    ...
    <previewJs>Vendor_WidgetPreview/js/my-preview-js-updates</previewJS>
    ...
</widget>

Real life demonstration :)

Here is a preview of MageOS_Widgetkit module (still under development at the time of writing).

adminhtml-preview adminhtml-preview-2 adminhtml-preview-3 adminhtml-preview-4 adminhtml-preview-5 adminhtml-preview-6

Here is the related widget.xml file:

<?xml version="1.0" ?>
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="urn:magento:module:MageOS_PageBuilderWidget:etc/widget.xsd">

    <widget id="mageos_slideshow" class="MageOS\Widgetkit\Block\Widgets\Slideshow"
            placeholder_image="MageOS_AdvancedWidget::view/frontend/templates/widget/images/slideshow.jpg">
        <label translate="true">MageOS Slideshow</label>
        <description translate="true">MageOS slideshow widget</description>
        <parameters>
            <parameter name="template" sort_order="5" xsi:type="select" visible="true">
                <label>Template</label>
                <options>
                    <option name="default" value="widget/uikit/slideshow.phtml" selected="true">
                        <label translate="true">MageOS UIkit themes Slideshow Template</label>
                    </option>
                    <option name="magento" value="widget/magento/slideshow.phtml">
                        <label translate="true">Magento base themes Slideshow Template</label>
                    </option>
                </options>
            </parameter>
            ...
        </parameters>
        <previewTemplates>
            <previewTemplate name="widget/uikit/slideshow.phtml" xsi:type="string">MageOS_Widgetkit::slideshow.phtml</previewTemplate>
            <previewTemplate name="widget/magento/slideshow.phtml" xsi:type="string">MageOS_Widgetkit::slideshow.phtml</previewTemplate>
        </previewTemplates>
        <previewBlock>MageOS\Widgetkit\Block\Adminhtml\Slideshow\Preview</previewBlock>
        <previewCss>MageOS_Widgetkit::css/uikit-pagebuilder.css</previewCss>
    </widget>

</widgets>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment