Let's create a skeleton for your next component. And mine too!
Let's create a component named skeleton. To have a fully working example,
we will need six files:
module_name
└── view/adminhtml
├── pagebuilder
│ └── content_type
│ └── skeleton.xml
├── layout
│ └── pagebuilder_skeleton_form.xml
├── ui_component
│ └── pagebuilder_skeleton_form.xml
└── web
├── js
│ └── skeleton.js
└── template
└── skeleton
├── master.html
└── preview.html
Let's start!
To add the new component to the sidebar, we need to declare it in the content_type file of our module. This file describes the component and its possible appearances. Each component must have at least one appearance.
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_PageBuilder:etc/content_type.xsd">
<type name="skeleton"
label="Skeleton"
component="Magento_PageBuilder/js/content-type"
preview_component="Vendor_Module/js/skeleton"
form="pagebuilder_skeleton_form"
menu_section="media"
icon="icon-pagebuilder-row"
sortOrder="40"
translate="label">
<children default_policy="deny"/>
<appearances>
<appearance default="true"
name="default"
preview_template="Vendor_Module/skeleton/preview"
master_template="Vendor_Module/skeleton/master"
reader="Magento_PageBuilder/js/master-format/read/configurable">
<elements>
<element name="main">
<style name="text_align" source="text_align"/>
<style name="border" source="border_style" converter="Magento_PageBuilder/js/converter/style/border-style"/>
<style name="border_color" source="border_color"/>
<style name="border_width" source="border_width" converter="Magento_PageBuilder/js/converter/style/border-width"/>
<style name="border_radius" source="border_radius" converter="Magento_PageBuilder/js/converter/style/remove-px"/>
<style name="display" source="display" converter="Magento_PageBuilder/js/converter/style/display" preview_converter="Magento_PageBuilder/js/converter/style/preview/display"/>
<style name="margins" storage_key="margins_and_padding" reader="Magento_PageBuilder/js/property/margins" converter="Magento_PageBuilder/js/converter/style/margins"/>
<style name="padding" storage_key="margins_and_padding" reader="Magento_PageBuilder/js/property/paddings" converter="Magento_PageBuilder/js/converter/style/paddings"/>
<attribute name="name" source="data-content-type"/>
<attribute name="appearance" source="data-appearance"/>
<css name="css_classes"/>
</element>
</elements>
</appearance>
</appearances>
</type>
</config>
Now, our component is visible in the sidebar's Media section and you can try dragging it into the page! However, it won't work.
Additionally, you may notice the 404 error in the browser console on initial page load.
This happens because Magento preloads all preview templates described in
content_type files but we haven't created preview.html yet.
Let's move on!
At this point, we need to create three files:
skeleton.js — Put the code for your component here:
file upload, additional control elements, etc.preview.html — Template used to render the component inside the Magento admin.master.html — Template used to save the component output for the frontend store.define([
'Magento_PageBuilder/js/content-type/preview',
'Magento_PageBuilder/js/content-type-menu/hide-show-option'
], function (Parent, HideShow) {
'use strict';
return class Skeleton extends Parent {
retrieveOptions() {
const options = super.retrieveOptions();
// Add "hide/show" icon
options.hideShow = new HideShow({
preview: this,
icon: HideShow.showIcon,
title: HideShow.showText,
action: this.onOptionVisibilityToggle,
classes: ['hide-show-content-type'],
sort: 40
});
return options;
}
};
});
<div class="pagebuilder-content-type pagebuilder-skeleton" event="{ mouseover: onMouseOver, mouseout: onMouseOut }, mouseoverBubble: false">
<render args="getOptions().template"></render>
<div attr="data.main.attributes" css="data.main.css" ko-style="data.main.style">Skeleton</div>
</div>
<div attr="data.main.attributes" css="data.main.css" ko-style="data.main.style">Skeleton</div>
Okay, you can now try inserting the component into the page.
Don't forget to insert the Row element first! Alternatively, install Melios Page Builder — it will automatically wrap the component in a Row when needed.
Now, click the "Edit" icon... And it doesn't work! Let's fix it!
We need to create two more files to fix the form rendering:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<uiComponent name="pagebuilder_skeleton_form"/>
</referenceContainer>
</body>
</page>
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd" extends="pagebuilder_base_form">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">pagebuilder_skeleton_form.pagebuilder_skeleton_form_data_source</item>
</item>
<item name="label" xsi:type="string" translate="true">Skeleton</item>
</argument>
<settings>
<deps>
<dep>pagebuilder_skeleton_form.pagebuilder_skeleton_form_data_source</dep>
</deps>
<namespace>pagebuilder_skeleton_form</namespace>
</settings>
<dataSource name="pagebuilder_skeleton_form_data_source">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="component" xsi:type="string">Magento_PageBuilder/js/form/provider</item>
</item>
</argument>
<dataProvider name="pagebuilder_skeleton_form_data_source" class="Magento\PageBuilder\Model\ContentType\DataProvider">
<settings>
<requestFieldName/>
<primaryFieldName/>
</settings>
</dataProvider>
</dataSource>
<fieldset name="appearance_fieldset" sortOrder="10" component="Magento_PageBuilder/js/form/element/dependent-fieldset">
<settings>
<imports>
<link name="hideFieldset">${$.name}.appearance:options</link>
<link name="hideLabel">${$.name}.appearance:options</link>
</imports>
</settings>
<field name="appearance" formElement="select" sortOrder="10">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="default" xsi:type="string">default</item>
</item>
</argument>
<formElements>
<select>
<settings>
<options>
<option name="0" xsi:type="array">
<item name="value" xsi:type="string">default</item>
<item name="label" xsi:type="string" translate="true">Default</item>
</option>
</options>
</settings>
</select>
</formElements>
</field>
</fieldset>
</form>
That's all! Our new component is fully functional in both Backend and Frontend!
You can now explore built-in Magento components to learn more and extend your basic component with additional fields and functionality.