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
.
https://gist.github.com/imranhsayed/974a0dbd37ce30adc5e9de4298e3ec35