#5 Attributes and Components in Gutenberg | RichText
Created by Imran Sayed Last updated January, 2020 English
In the previous blog, we learned about how edit
and save
functions work. They describe the structure of the block’s appearance. However, they only returned simple paragraphs. In this blog, we will learn about how the block’s structure can be changed when the user changes a block.
State of a block:
To achieve dynamic change in the block’s structure when the user changes a block, a state of a block
is maintained through the editing session as a plain JavaScript object.
Every time block is updated the edit function is called.
Attributes:
To extract the JavaScript object again from the saved content of a post and reuse it we use block type’s attribute property.
They provide a mechanism to map from the saved markup to a JavaScript representation of a block.
Attribute Sources:
Attribute Sources help you extract block attribute values from saved post content. They help you map from the saved markup to a JavaScript representation of a block. If no attribute source
is specified, the attribute will be saved to (and read from) the block’s comment delimiter.
hpq
: Attribute sources are a superset of functionality provided by hpq, a small library used to parse and query HTML markup into an object shape.
There are different types of attributes sources you can use. For example children, attribute, text, html, query, meta
Example of an attributes source: 'meta'
registerBlockType( 'myguten-block/test-block', {
attributes: {
content: {
type: 'array',
source: 'children',
selector: 'p'
},
},
When you define these attributes into registerBlockType(), it is passed to the edit()
and save()
source: ‘children’
means it will look for the text inside of selector <p>
The way you use it into your edit function:
edit( props ) {let { attributes , setAttributes, className } = props;
function onChange( event ) {
setAttributes( { author: event.target.value } );
}
return <p onChange={ onChange }/>{ attributes.content }</p>;
},
Once it’s saved into the database, it can be extracted using props.attributes
save: ( props ) => {
console.log( 'save-props', props );
return (
<p>{ props.attributes.content } </p>
);
}
Comment Delimiter
By storing data in HTML comments we would know that we wouldn’t break the rest of the HTML in the document, that browsers should ignore it, and that we could simplify our approach to parsing the document.
Let’s create an attribute,
registerBlockType( 'myguten-block/test-block', {
title: 'Basic Example',
icon: 'smiley',
category: 'layout',attributes: {
contentStyle: {
type: 'object',
default: {
color: 'black',
textAlign: 'left'
}
}
},
}
When we don’t specify a source in the attribute contentStyle, the data gets saved in the comment delimiter. And it can be extracted in the save
function using props.attributes.contentStyle
.
Benefits of using Comment Delimiter
- Whereas HTML attributes are complicated to parse properly, comments are quite easily described by a leading
<!-- followed by anything except -- until the first -->
. This simplicity and permissiveness means that the parser can be implemented in several ways without needing to understand HTML properly. - We can use JSON literals inside the comment.
- These explicit boundaries also protect damage in a single block from bleeding into other blocks or tarnishing the entire document.
Gutenberg Components
Because many blocks share the same complex behaviors, reusable components are made available to simplify implementations of your block’s edit
function. The common one’s are:
- RichText
- BlockControls
- AlignmentToolbar
- Inspect
- ColorPalette
You can find components in the Gutenberg git repo
https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/
1-RichText Component
Instead of creating DOM nodes using createElement()
, we can encapsulate this behavior using Components
. Components provide reusability and allow you to hide the complexity into their self-contained units. There are a number of components available. Let’s talk about one of them, called RichText
component. It can be considered as textarea
element that enables rich content editing including bold, italics, hyperlinks, etc.
You can find RichText Component defined in https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/rich-text/index.js
Please make sure to add wp-editor
to the dependency array of registered script handles when calling wp_register_script
.
Return value of registerBlockType()
If you console log( results )
, what is returned by registerBlockType(), you get:
attributes:
className: {type: "string"}
__proto__: Object
category: "layout"
edit: ƒ edit(props)
icon: {src: "smiley"}
name: "myguten-block/test-block"
save: ƒ save()
title: "Basic Example"
Props
If you console.log( props )
inside edit() and when you edit something you get the following data in props
// Result for console.log( props );
attributes:
content: ["h"]
__proto__: Object
className: "wp-block-myguten-block-test-block"
clientId: "be406ad0-a7e6-45ca-b47d-5ff44673b280"
insertBlocksAfter: ƒ ()
isSelected: true
isSelectionEnabled: true
mergeBlocks: ƒ ()
name: "myguten-block/test-block"
onReplace: ƒ ()
setAttributes: ƒ ()
toggleSelection: ƒ ()
2-BlockControls and AlignmentToolbar
If the return value of your block type’s edit
function includes a BlockControls
element, those controls will be shown in the selected block’s toolbar. This will show a number of control buttons may be shown in a toolbar above the selected block.
3-Inspect & ColorPalette Component
The inspector is used to display less-often-used settings or settings that require more screen space
If you include an InspectorControls
element in the return value of your block type’s edit
function add some content inside of it, those controls and content will be shown in the inspector region.
Let’s add ColorPalette
Component inside of it. What we want to achieve is that when the user selects any color on the palette, the text color of our custom block should change to that one.
https://github.com/imranhsayed/myguten-block/tree/inspector-controls-component
WordPress Core:
You can find the Gutenberg JavaScript core files inside Gutenberg Git repo https://github.com/WordPress/gutenberg/.
For example, registerBlockType() resides in https://github.com/WordPress/gutenberg/blob/master/packages/blocks/src/api/registration.js.
Also, you can find components in the Gutenberg git repo
https://github.com/WordPress/gutenberg/blob/master/packages/block-editor/src/components/