Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Widgets/Blocks with Magento Page Builder
Gabriel Lima
Gabriel Lima

Posted on

Widgets/Blocks with Magento Page Builder

This guide explains how to render dynamic content in Magento Page Builder using Blocks or Widgets without
relying on the native "HTML Code" content type.

This guide is based on a custom content type generated
usingcommerce-docs/pbmodules.

Requirements

  • A pre-configured Custom Page Builder or anew installation.
  • Block Class and .phtml template file
  • (Optional) Awidget.xml file if you choose to use the widget setup. If using a block-based implementation, thewidget.xml file is not required.

this tutorial as created based on the custom content type that was generated by
thehttps://github.com/commerce-docs/pbmodules

1. Update Dependency Injection (DI) Configuration

Create or update your module'setc/di.xml, add the following code.

<typename="Magento\PageBuilder\Model\Stage\RendererPool"><arguments><argumentname="renderers"xsi:type="array"><itemname="CONTENT_TYPE_NAME"xsi:type="object">                Magento\PageBuilder\Model\Stage\Renderer\WidgetDirective</item></argument></arguments></type>
Enter fullscreen modeExit fullscreen mode

Note: ReplaceCONTENT_TYPE_NAME with your content type name.

2. Content Type XML Configuration

Create or update the file:view/adminhtml/pagebuilder/content_type/CONTENT_TYPE_NAME.xml

  • Within the section:
    Add an HTML attribute (inside or any other element as needed):

    <htmlname="html"preview_converter="Magento_PageBuilder/js/converter/attribute/preview/store-id"/>
  • After the</elements>:
    Add the converters configuration.

    <converters><convertercomponent="Vendor_Module/js/content-type/CONTENT_TYPE_FOLDER/mass-converter/widget-directive"name="widget_directive"><config><itemname="html_variable"value="html"/></config></converter></converters>

Note: ReplaceCONTENT_TYPE_FOLDER with your content type folder name.

3. Create the Mass Converter JavaScript

Create the file:view/adminhtml/web/js/content-type/CONTENT_TYPE_FOLDER/mass-converter/widget-directive.js
Add the following code:

Note: ReplaceCONTENT_TYPE_FOLDER with your content type folder name.

define(['Magento_PageBuilder/js/mass-converter/widget-directive-abstract','Magento_PageBuilder/js/utils/object'],function(widgetDirective,dataObject){'use strict';classWidgetDirectiveextendswidgetDirective{/**         * Convert value to internal format         *         * @param {object} data         * @param {object} config         * @returns {object}         */fromDom(data,config){varattributes=super.fromDom(data,config);returndata;}toDom(data,config){constattributes={type:'Devgfnl\\WidgetBlockPageBuilder\\Block\\Info',template:'Devgfnl_WidgetBlockPageBuilder::info.phtml',type_name:'Widget/Block with PageBuilder',my_field:data.my_field// ... other attributes to be passed to the block/widget};dataObject.set(data,config.html_variable,this.buildDirective(attributes));returndata;}}returnWidgetDirective;});
Enter fullscreen modeExit fullscreen mode

Using a Block Instead of a Widget
If you are not using the widget setup, modify the toDom function as follows:

        toDom(data, config) {            const attributes = {-               type: 'Devgfnl\\WidgetBlockPageBuilder\\Block\\Info',+               class: 'Devgfnl\\WidgetBlockPageBuilder\\Block\\Info',                template: 'Devgfnl_WidgetBlockPageBuilder::info.phtml',                type_name: 'Widget/Block with PageBuilder',                my_field: data.my_field            };-           dataObject.set(data, config.html_variable, this.buildDirective(attributes));+           dataObject.set(data, config.html_variable, this.buildBlockDirective(attributes));            return data;        }+       buildBlockDirective(attributes) {+           return '{{block ' + this.createAttributesString(attributes) + '}}';+       }
Enter fullscreen modeExit fullscreen mode

Note: When using a widget, ensure that you have the proper widget.xml setup; otherwise, the Page Builder will not
render the PHTML content. The block-based approach is recommended if you want to avoid creating an extra widget.xml
file.

4. Update the Preview JavaScript

Create or update the fileview/adminhtml/web/js/content-type/CONTENT_TYPE_FOLDER/preview.js file, update it with the
following code.

Note: ReplaceCONTENT_TYPE_FOLDER with your content type folder name.

define(['jquery','mage/translate','knockout','underscore','Magento_PageBuilder/js/config','Magento_PageBuilder/js/content-type/preview'],function($,$t,ko,_,Config,PreviewBase){'use strict';var$super;/**     * Quote content type preview class     *     * @param parent     * @param config     * @param stageId     * @constructor     */functionPreview(parent,config,stageId){PreviewBase.call(this,parent,config,stageId);this.displayPreview=ko.observable(false);this.previewElement=$.Deferred();this.loading=ko.observable(false);this.widgetUnsanitizedHtml=ko.observable();this.element=null;this.messages={EMPTY:$t('Empty...'),NO_RESULTS:$t('No result were found.'),LOADING:$t('Loading...'),UNKNOWN_ERROR:$t('An unknown error occurred. Please try again.')};this.placeholderText=ko.observable(this.messages.EMPTY);}Preview.prototype=Object.create(PreviewBase.prototype);$super=PreviewBase.prototype;/**     * Modify the options returned by the content type     *     * @returns {*}     */Preview.prototype.retrieveOptions=function(){varoptions=$super.retrieveOptions.call(this,arguments);// Customize options herereturnoptions;};/**     * On afterRender callback.     *     * @param {Element} element     */Preview.prototype.onAfterRender=function(element){this.element=element;this.previewElement.resolve(element);};/**     * @inheritdoc     */Preview.prototype.afterObservablesUpdated=function(){$super.afterObservablesUpdated.call(this);constdata=this.contentType.dataStore.getState();if(this.hasDataChanged(this.previousData,data)){this.displayPreview(false);if(!this.shouldDisplay(data)){this.placeholderText(this.messages.EMPTY);return;}consturl=Config.getConfig('preview_url'),requestConfig={// Prevent cachingmethod:'POST',data:{role:this.config.name,directive:this.data.main.html()}};this.placeholderText(this.messages.LOADING);$.ajax(url,requestConfig).done((response)=>{if(typeofresponse.data!=='object'||!response.data.content){this.placeholderText(this.messages.NO_RESULTS);return;}if(response.data.error){this.widgetUnsanitizedHtml(response.data.error);}else{this.widgetUnsanitizedHtml(response.data.content);this.displayPreview(true);}this.previewElement.done(()=>{$(this.element).trigger('contentUpdated');});}).fail(()=>{this.placeholderText(this.messages.UNKNOWN_ERROR);});}this.previousData=Object.assign({},data);};/**     * Determine if the preview should be displayed     *     * @param data     * @returns {boolean}     */Preview.prototype.shouldDisplay=function(data){constmyField=data.my_field;return!!myField;};/**     * Determine if the data has changed, whilst ignoring certain keys which don't require a rebuild     *     * @param {object} previousData     * @param {object} newData     * @returns {boolean}     */Preview.prototype.hasDataChanged=function(previousData,newData){previousData=_.omit(previousData,this.ignoredKeysForBuild);newData=_.omit(newData,this.ignoredKeysForBuild);return!_.isEqual(previousData,newData);};returnPreview;});
Enter fullscreen modeExit fullscreen mode

5. Create the Preview Template

Create or update the file preview template file:
view/adminhtml/web/template/content-type/CONTENT_TYPE_FOLDER/default/preview.html, add
the following code:

Note: ReplaceCONTENT_TYPE_FOLDER with your content type folder name.

<divclass="pagebuilder-content-type"attr="data.main.attributes"ko-style="data.main.style"css="data.main.css"event="{ mouseover: onMouseOver, mouseout: onMouseOut }, mouseoverBubble: false"><divclass="my-class"data-bind="liveEdit: { field: 'my_field', placeholder: $t('Your custom content type!') }"></div><divif="displayPreview"class="rendered-content"html="widgetUnsanitizedHtml"afterRender="onAfterRender"></div><divifnot="displayPreview"class="pagebuilder-products-placeholder"><spanclass="placeholder-text"text="placeholderText"></span></div><renderargs="getOptions().template"></render></div>
Enter fullscreen modeExit fullscreen mode

6. Create the Master Template

Create or update the file master template file:
view/adminhtml/web/template/content-type/CONTENT_TYPE_FOLDER/default/master.html, add the
following code:

Note: ReplaceCONTENT_TYPE_FOLDER with your content type folder name.

<divhtml="data.main.html"attr="data.main.attributes"css="data.main.css"ko-style="data.main.style"></div>
Enter fullscreen modeExit fullscreen mode

Results

Image description

Observations

  • KnockoutJS Rendering: In tests, a PHTML file incorporating KnockoutJS rendered correctly on the frontend. However,KnockoutJS may not render as expected in the admin area.
  • Widget vs. Block: If you use the widget setup, ensure that the correspondingwidget.xml is configured properly;otherwise, the PHTML content may not be rendered. The block-based approach is recommended for simplicity, as it doesnot require an extra XML configuration file.
  • BlockInterface: If you use the block and widget approach, ensure that the Block class implements theBlockInterface to avoid any issues with the Page Builder rendering the content.

Known Issues & Solutions

  • Issue: The PHTML content is not rendered in the admin area.
    • Solution:
      • If you are using the widget setup, ensure that thewidget.xml file is configured properly.
      • Ensure that the Block class implements theBlockInterface.

Code Reference

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Location
    Brazil
  • Joined

More fromGabriel Lima

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp