Volto: Customizing Blocks
Use Case
The content of a page should be teasered: Show first part and the rest on click on "read more".
Question
How does the view know what to hide on first rendering?
Solution
I enriched the default Volto text block with an additional attribute "readmore".
src/customizations/components/manage/Blocks/Text/Schema.jsx
import BlockSettingsSchema from '@plone/volto/components/manage/Blocks/Block/Schema';
const Schema = {
...BlockSettingsSchema,
fieldsets: [
{
...BlockSettingsSchema.fieldsets[0],
fields: ['readmore'],
},
],
properties: {
readmore: {
title: 'Read more',
description: 'Hide following text. Show on Click.',
type: 'boolean',
},
},
};
export default Schema;
src/customizations/components/manage/Blocks/Text/Edit.jsx
import { SidebarPortal } from '@plone/volto/components';
import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
import schema from './Schema';
snip
render() {
snip
return (
<>
<SidebarPortal selected={this.props.selected}>
<InlineForm
schema={schema}
title={schema.title}
onChangeField={(id, value) => {
this.props.onChangeBlock(this.props.block, {
...this.props.data,
[id]: value,
});
}}
formData={this.props.data}
/>
</SidebarPortal>
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.
The following modification forces the sidebar to show the block configuration pane instead the one of the document.
src/config.js
const customizedBlocks = {
text: {
...defaultBlocks.blocksConfig.text,
sidebarTab: 1,
},
};
export const blocks = {
...defaultBlocks,
blocksConfig: {
...defaultBlocks.blocksConfig,
...customBlocks,
...customizedBlocks,
},
};
Now a view of the page can distinguish between content blocks to show and these to hide for further reading on click.
See also volto-newsblock on github for a custom teaser block.