-
-
Notifications
You must be signed in to change notification settings - Fork 756
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Block examples documentation #6560
Changes from 40 commits
dccee83
bea33fd
8cd8e6f
bfe8c56
485a42c
992d234
8228d2d
1ecbe10
12efde1
d54d289
476a36b
9c09ad9
4d75f66
68c42a4
a75f94a
7907f50
13056b1
8eb9ea2
de133a9
5b70643
e507eed
3fc9aa2
6896154
ff52fee
ef09838
f87d1b4
aa274bc
9a56331
524f007
938ae9a
34e4423
158ec29
9e34489
682871d
a7d2fc0
4e5b9e0
d149cfe
739e588
3d83b54
bc5e436
a8cbfb0
3102b4d
ad7b2c0
59328e7
83405f8
5244365
8dbf8f8
43d0fa6
720b3e2
c06b755
591505f
f1abca2
058b4b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
--- | ||
myst: | ||
html_meta: | ||
"description": "Volto block with custom schema and view components" | ||
"property=og:description": "Volto block with custom schema and view components" | ||
"property=og:title": "Volto block with custom schema and view components" | ||
"keywords": "Volto, React, blocks, grid, container, Plone" | ||
--- | ||
|
||
(custom-schema-and-view)= | ||
|
||
# Block with a custom schema | ||
|
||
You can create a block with several settings defined using a schema, and let Volto render the edit form by itself. | ||
|
||
To do so, define the schema, the view component, and configure the block settings. | ||
|
||
## Preparations | ||
|
||
In your Volto add-on, create a subfolder {file}`ExampleBlock02` inside the {file}`components` folder to save all the files required to create a block. | ||
|
||
## Schema | ||
|
||
Create a {file}`Schema.js` file inside the {file}`ExampleBlock02` folder, with the following contents. | ||
|
||
```js | ||
import messages from './messages'; | ||
|
||
const Schema = ({ intl }) => { | ||
return { | ||
title: intl.formatMessage(messages.block02), | ||
block: 'block02', | ||
fieldsets: [ | ||
{ | ||
id: 'default', | ||
title: intl.formatMessage(messages.default), | ||
fields: ['url', 'title'], | ||
}, | ||
], | ||
|
||
properties: { | ||
url: { | ||
title: intl.formatMessage(messages.URL), | ||
widget: 'url', | ||
}, | ||
title: { | ||
title: intl.formatMessage(messages.title), | ||
}, | ||
}, | ||
required: [], | ||
}; | ||
}; | ||
|
||
export default Schema; | ||
``` | ||
|
||
## Messages | ||
|
||
As you may have noted, you prepared the block for internationalization. | ||
{term}`Internationalization` (i18n) is the process of creating user interfaces which are suitable for different languages and cultural contexts. | ||
To add translatable messages, create a file {file}`messages.js` in the same {file}`ExampleBlock02` folder with the following contents. | ||
|
||
```js | ||
import { defineMessages } from 'react-intl'; | ||
|
||
const messages = defineMessages({ | ||
block02: { | ||
id: 'block02', | ||
defaultMessage: 'Block 02', | ||
}, | ||
default: { | ||
id: 'default', | ||
defaultMessage: 'Default', | ||
}, | ||
URL: { | ||
id: 'URL', | ||
defaultMessage: 'URL', | ||
}, | ||
title: { | ||
id: 'title', | ||
defaultMessage: 'Title', | ||
}, | ||
}); | ||
|
||
export default messages; | ||
``` | ||
|
||
## View component | ||
|
||
The view component will have all the required logic to show the information saved on the block. | ||
It will be a small HTML fragment. | ||
|
||
Create a file {file}`View.jsx` in the {file}`ExampleBlock02` folder with the following contents. | ||
|
||
```jsx | ||
import cx from 'classnames'; | ||
import React from 'react'; | ||
|
||
const View = (props) => { | ||
// `data` holds the values entered in the block edit form. | ||
// `className` holds the CSS class names injected into this block by Volto's `styleClassNameExtenders`. | ||
// `style` holds the CSS properties injected into this block by Volto's `Block Sytle Wrapper`. | ||
erral marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const { data, className, style } = props; | ||
return ( | ||
<div className={cx('block', 'block02', className)} style={style}> | ||
I am the Block view component! | ||
<ul> | ||
<li>Title: {data.title}</li> | ||
<li>URL: {data.url}</li> | ||
</ul> | ||
</div> | ||
); | ||
}; | ||
|
||
export default View; | ||
``` | ||
|
||
## Block configuration | ||
|
||
With all the block components ready, you need to register the block into Volto. | ||
|
||
To do so, open your add-on's {file}`index.js` file, and insert the following contents. | ||
|
||
```js | ||
const applyConfig = (config) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @erral I don't think this info should be here. It has nothing to do with the example given here. I would show the contents of the index file that is created whenever you create a new add-on. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will rewrite this, saying to add the block configuration form before the |
||
config.settings.isMultilingual = false; | ||
config.settings.supportedLanguages = ['en']; | ||
config.settings.defaultLanguage = 'en'; | ||
|
||
|
||
return config; | ||
} | ||
|
||
export default applyConfig; | ||
``` | ||
|
||
Before the last `return config;` statement, write the following configuration. | ||
|
||
```js | ||
config.blocks.blocksConfig.block02 = { | ||
id: 'block02', // this is the block id, it must match the id on the previous line | ||
title: 'Block 02', // this is the block title | ||
view: View02, // this is the block's view component | ||
// edit: null; | ||
erral marked this conversation as resolved.
Show resolved
Hide resolved
|
||
blockSchema: Schema02, // this is the schema that will be used to render the edit form | ||
icon: imagesSVG, // this is the image that will be shown in the block selector | ||
sidebarTab: 1, // this is set to 1 to have the `Block` tab selected in the sidebar editor when editing this block | ||
}; | ||
``` | ||
|
||
At the top of the file, import the relevant components as follows. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @erral I would flip this info to be added before the info from here |
||
|
||
```js | ||
import View02 from './components/ExampleBlock02/View'; | ||
import Schema02 from './components/ExampleBlock02/Schema'; | ||
|
||
// This is the icon we use for the example, use a meaningful one or provide your own image. | ||
import imagesSVG from '@plone/volto/icons/images.svg'; | ||
``` | ||
|
||
## See it in action | ||
|
||
Your block is ready to be used in your site. | ||
stevepiercy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Restart your Volto site, and you can add it using the block add form. | ||
erral marked this conversation as resolved.
Show resolved
Hide resolved
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@erral this is the first document that you have created why do we have example block 02? it makes more sense for me to start with ExampleBlock01 or simply have block1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrll, this comes from examples I have written for my team. There are 6 examples, but I have brought here only 3, the most relevant ones. I have copy-pasted the code, so that's why we have 2, 5 and 6.
I haven't copied the following ones: