In Getting Started with Custom Blocks in Volto, we walked through the basic structure setup for a custom block and registered it with Plone’s React-based frontend, Volto. Now, let’s review the simple Edit Component in src/components/Blocks/MyCustomBlock/
.
Edit.jsx
import React from 'react'; const Edit = props => { return <div>I'm the Block edit component!</div>; }; export default Edit;
Currently, the Edit Block displays the text “I'm the Block edit component!,” but there’s not a way to actually edit anything. Don’t worry — Volto’s Sidebarportal
component can be used to extend the Edit component.
When in Edit mode, the right sidebar panel (separate from main body of the page) displays additional information. The right sidebar panel typically features a Document tab which addresses the overall page and a Block tab which displays information specific to the selected Block.
First, add the SidebarPortal
component to Edit.jsx
. Everything inside the SidebarPortal
will be displayed in the right sidebar panel. Next, you’ll need to destructure selected
, onChangeBlock
, block
, data
from props to support the Block’s functionality.
Visit the Volto Developer Documentation for a complete list of props.
Edit.jsx
import { SidebarPortal } from '@plone/volto/components'; ... const Edit = props => { const { selected, onChangeBlock, block, data } = props; return ( <div> <SidebarPortal selected={selected}> I'm the Sidebar panel! </SidebarPortal> <div>I'm the Block edit component!</div> </div> ) };
Screenshot of Volto Edit mode. In the right sidebar panel, the Block tab is selected. “I’m the Sidebar Panel!” is displayed in the Block tab.
Before building the form, let’s move the Sidebar code into its own component to keep things neat and organized.
Create Data.jsx
in src/components/Blocks/MyCustomBlock/
.
Data.jsx
import React from 'react'; const Data = (props) => { const { block, data, onChangeBlock } = props; return ( <> I'm the Sidebar panel woo! </> ); }; export default Data;
Next, Import Data.jsx
into Edit.jsx
. Then, replace the contents of Sidebarportal
with the Data
component. The Data component will need access to the Block data, so the Data component will also need to be passed to the Edit component’s props.
Edit.jsx
import Data from './Data'; ... const Edit = props => { const { selected, onChangeBlock, block, data } = props; return ( <div> <SidebarPortal selected={selected}> <Data {...props} data={data} block={block} onChangeBlock={onChangeBlock} /> </SidebarPortal> <div>I'm the Block edit component!</div> </div> ) };
The Edit form can be created with either the InlineForm
or the BlockDataForm
component. Since I plan to use a schema-based form, I chose to use the BlockDataForm
component.BlockDataForm
is a convenience component that wraps the InlineForm
component with withVariationSchemaEnhancer
. This allows for easy use of Volto Extensions such as variations and schema enhancers.
First, Schema.js
will need to be created in src/components/Blocks/MyCustomBlock/
to store the form schema.
Schema.js
export const DataSchema = (props) => { return { title: 'My Custom Blocks Form', fieldsets: [ { id: 'default', title: 'Default', fields: ['href', 'title', 'subtitle', 'bg_image', 'openLinkInNewTab'], }, ], properties: { href: { title: 'Link', widget: 'object_browser', mode: 'link', selectedItemAttrs: [ 'Title', 'Description', ], allowExternals: true, }, title: { title: 'Title', }, subtitle: { title: 'Subtitle Text', widget: 'textarea', }, bg_image: { title: 'Background Image', widget: 'object_browser', mode: 'image', allowExternals: true, }, openLinkInNewTab: { title: 'Open Link in New Tab', type: 'boolean', }, }, required: [], }; };
The Link and Background Images fields use Volto’s ObjectBrowserWidget
to find content within the site. The default mode forObjectBrowserWidget
is multiple, but, in this scenario,ObjectBrowserWidget
is using the link and image mode to limit the fields. Visit Volto’s Developer Documentation to learn more about ObjectBrowserWidget and its settings.
Next, we import Schema.js into the Data component.
Data.jsx
import { BlockDataForm } from '@plone/volto/components'; import { DataSchema } from './schema'; ... const Data = (props) => { const { block, data, onChangeBlock } = props; const schema = DataSchema({ ...props }); return ( <BlockDataForm schema={schema} title={schema.title} onChangeField={(id, value) => { onChangeBlock(block, { ...data, [id]: value, }); }} formData={data} block={block} /> ); }; export default Data;
Now, you have the Edit form displayed in the sidebar panel.
Share your Volto projects with us, and sign up for our newsletters to get the latest tech tips in your inbox.