39. Custom Block#

In case you need some special look of a paragraph, a special behavior like an image gallery or even need to display data as chart, then you want to create your own block.

A very simple use case where the default text block can be extended to achieve the requested look and behavior is the following:

Use Case: The content of a page should be teasered: Show first part and the rest on click on "read more".

Volto text block with teasering behavior
Edit view with an additonal option

We extend the default Volto text block schema with an additional field "readmore".


 1import BlockSettingsSchema from '@plone/volto/components/manage/Blocks/Block/Schema';
 3const Schema = {
 4    ...BlockSettingsSchema,
 5    fieldsets: [
 6        {
 7            ...BlockSettingsSchema.fieldsets[0],
 8            fields: ['readmore'],
 9        },
10    ],
11    properties: {
12        readmore: {
13        title: 'Read more',
14        description: 'Hide following text. Show on Click.',
15        type: 'boolean',
16        },
17    },
20export default Schema;

We use the Volto InlineForm component to extend the sidebar.


 1import { SidebarPortal } from '@plone/volto/components';
 2import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
 4import schema from './Schema';
 8render() {
12    return (
13        <>
14            <SidebarPortal selected={this.props.selected}>
15                <InlineForm
16                    schema={schema}
17                    title={schema.title}
18                    onChangeField={(id, value) => {
19                        this.props.onChangeBlock(this.props.block, {
20                            ...this.props.data,
21                            [id]: value,
22                        });
23                    }}
24                    formData={this.props.data}
25                />
26            </SidebarPortal>

You see the call of onChangeBlock which writes the value true or false to the block data.

With the above customizations the default text block has an additional attribute "readmore".

The default text block has no options to select, so it is per default configured to show the document properties pane in sidebar and not the block pane. The following modification forces the sidebar to show the block configuration pane instead.


 1const customizedBlocks = {
 2    text: {
 3        ...config.blocks.blocksConfig.text,
 4        sidebarTab: 1,
 5    },
 8export const blocks = {
 9    ...config.blocks,
10    blocksConfig: {
11        ...config.blocks.blocksConfig,
12        ...customBlocks,
13        ...customizedBlocks,
14    },

The blocksConfig is modified by a setting for the text block: Show pane 1 (we have two panes: pane 0 with the document fields and pane 1 with the block fields which depend on the block type).

Now a view of the page can distinguish between content blocks to show and these to hide for further reading on click.

39.1. Exercise#

Add a field highlighted to a default text block. With this marker you can add a CSS rule to highlight the blocks marked. Where would you place this CSS rule?

39.2. Prospect#

That was easy. But what if we need a FAQ section and want to provide a nice form for question and answer pairs? See the next chapter where we create a new block type. We take the opportunity to create an add-on with this block type. So the feature can be easily applied to multiple projects.