-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Docs: Fundamentals of Block Development - The block wrapper #56596
Merged
juanmaguitar
merged 22 commits into
trunk
from
fundamentals-block-development/the-block-wrapper
Nov 29, 2023
Merged
Changes from 10 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
3037f59
Add The Block Wrapper
juanmaguitar 74cb3ef
Refactor block wrapper and add useBlockProps hook
juanmaguitar 49c08ab
Update block wrapper in the Block Editor
juanmaguitar 1a8eeb7
Update block markup and wrappers
juanmaguitar 48b510e
Update block markup and wrapper attributes
juanmaguitar 42d9fc5
Update block wrapper attributes and add documentation
juanmaguitar 8668e4a
Merge branch 'trunk' into fundamentals-block-development/the-block-wr…
juanmaguitar f408e65
Content added
juanmaguitar 7807271
Fix server-side render definition for block
juanmaguitar 01c955b
Refactor block wrapper markup
juanmaguitar 5b58cea
Update docs/getting-started/fundamentals-block-development/the-block-…
juanmaguitar 0710168
Update docs/getting-started/fundamentals-block-development/the-block-…
juanmaguitar 4d0ff8d
Update docs/getting-started/fundamentals-block-development/the-block-…
juanmaguitar e03b686
Update docs/getting-started/fundamentals-block-development/the-block-…
juanmaguitar 3c60893
Update docs/getting-started/fundamentals-block-development/the-block-…
juanmaguitar aa154a2
Fix save function in block wrapper
juanmaguitar 7a4ead2
Refactor block wrapper markup to add attributes
juanmaguitar fe8f253
update folder name
juanmaguitar 2069667
Merge branch 'trunk' into fundamentals-block-development/the-block-wr…
juanmaguitar 8b9532d
Add block-wrapper.md to toc.json
juanmaguitar a4d1919
Add link create-block
juanmaguitar 6c0925f
fixed link Metadata in block.json
juanmaguitar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
113 changes: 113 additions & 0 deletions
113
docs/getting-started/fundamentals-block-development/the-block-wrapper.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# The block wrapper | ||
|
||
Each block's markup is wrapped by a container HTML tag that needs to have the proper attributes to fully work in the Block Editor and to reflect the proper block's style settings when rendered in the Block Editor and the front end. As developers, when creating a custom block, we need to manually add these attributes to the markup using some of the tools provided by WordPress. | ||
|
||
Ensuring proper attributes to the block wrapper is especially important when using custom styling or features like `supports`. | ||
|
||
<div class="callout callout-info"> | ||
The use of <code>supports</code> generates a set of properties that need to be manually added to the wrapping element of the block so they're properly stored as part of the block data | ||
</div> | ||
|
||
A block can have three markups defined, each one of them with a specific target and purpose: | ||
juanmaguitar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- The one for the **Block Editor**, defined through a `edit` React component passed to `registerBlockType` when registering the block in the client. | ||
- The one used to **save the block in the DB**, defined through a `save` React component passed to `registerBlockType` when registering the block in the client. | ||
ryanwelcher marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- This markup will be returned to the front end on request if no dynamic render has been defined for the block. | ||
- The one used to **dynamically render the markup of the block** returned to the front end on request, defined through the `render_callback` on `register_block_type` or the `render` PHP file in `block.json` | ||
- If defined, this server-side generated markup will be returned to the front end, ignoring the markup stored in DB. | ||
|
||
For the React components `edit` and `save`, the block wrapper element should be a native DOM element (like `<div>`) or a React component that forwards any additional props to native DOM elements. Using a <Fragment> or <ServerSideRender> component, for instance, would be invalid. | ||
juanmaguitar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
## The Edit component's markup | ||
|
||
The `useBlockProps()` hook available on the `@wordpress/block-editor` allows passing the required attributes for the Block Editor to the `edit` block's outer wrapper. | ||
|
||
Among other things, the `useBlockProps()` hook takes care of including in this wrapper: | ||
- An `id` for the block's markup | ||
- Some accesibility and `data-` attributes | ||
- Classes and inline styles reflecting custom settings, which include by default: | ||
- The `wp-block` class | ||
- A class that contains the name of the block with its namespace | ||
|
||
For example, for the following piece of code of a block's registration in the client... | ||
|
||
```js | ||
const Edit = () => <p { ...useBlockProps() }>Hello World - Block Editor</p>; | ||
|
||
registerBlockType( ..., { | ||
edit: Edit | ||
} ); | ||
``` | ||
_(see the [code above](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/minimal-block-ca6eda/src/index.js) in [an example](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/minimal-block-ca6eda))_ | ||
|
||
...the markup of the block in the Block Editor could look like this: | ||
```html | ||
<p | ||
tabindex="0" | ||
id="block-4462939a-b918-44bb-9b7c-35a0db5ab8fe" | ||
role="document" | ||
aria-label="Block: Minimal Gutenberg Block ca6eda" | ||
data-block="4462939a-b918-44bb-9b7c-35a0db5ab8fe" | ||
data-type="block-development-examples/minimal-block-ca6eda" | ||
data-title="Minimal Gutenberg Block ca6eda" | ||
class=" | ||
block-editor-block-list__block | ||
wp-block | ||
is-selected | ||
wp-block-block-development-examples-minimal-block-ca6eda | ||
" | ||
>Hello World - Block Editor</p> | ||
``` | ||
|
||
Any additional classes and attributes for the `Edit` component of the block should be passed as an argument of `useBlockProps` (see [example](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/stylesheets-79a4c3/src/edit.js)). When you add `support` for any feature, they get added to the object returned by the `useBlockProps` hook. | ||
|
||
|
||
## The Save component's markup | ||
|
||
When saving the markup in the DB, it’s important to add the block props returned by `useBlockProps.save()` to the wrapper element of your block. `useBlockProps.save()` ensures that the block class name is rendered properly in addition to any HTML attribute injected by the block supports API. | ||
|
||
For example, for the following piece of code of a block's registration in the client that defines the markup desired for the DB (and returned to the front end by default)... | ||
|
||
```js | ||
const Save = () => <p { ...useBlockProps.save() }>Hello World - Frontend</p>; | ||
juanmaguitar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
registerBlockType( ..., { | ||
edit: Edit, | ||
save: Save, | ||
juanmaguitar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} ); | ||
``` | ||
|
||
_(see the [code above](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/minimal-block-ca6eda/src/index.js) in [an example](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/minimal-block-ca6eda))_ | ||
|
||
|
||
...the markup of the block in the front end could look like this: | ||
```html | ||
<p class="wp-block-block-development-examples-minimal-block-ca6eda">Hello World – Frontend</p> | ||
``` | ||
|
||
Any additional classes and attributes for the `Save` component of the block should be passed as an argument of `useBlockProps.save()` (see [example](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/stylesheets-79a4c3/src/save.js)). | ||
juanmaguitar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
When you add `support` for any feature, the proper classes get added to the object returned by the `useBlockProps.save()` hook. | ||
|
||
```html | ||
<p class=" | ||
wp-block-block-development-examples-block-supports-6aa4dd | ||
has-accent-4-color | ||
has-contrast-background-color | ||
has-text-color | ||
has-background | ||
">Hello World</p> | ||
``` | ||
|
||
_(check the [example](https://github.com/WordPress/block-development-examples/tree/trunk/plugins/block-supports-6aa4dd) that generated the HTML above in the front end)_ | ||
|
||
## The server-side render markup | ||
|
||
Any markup in the server-side render definition for the block can use the [`get_block_wrapper_attributes()`](https://developer.wordpress.org/reference/functions/get_block_wrapper_attributes/) to generate the string of attributes required to reflect the block settings. function (see [example](https://github.com/WordPress/block-development-examples/blob/trunk/plugins/copyright-date-block-09aac3/src/render.php#L31)). | ||
|
||
```php | ||
<p <?php echo get_block_wrapper_attributes(); ?>> | ||
<?php esc_html_e( 'Block with Dynamic Rendering – hello!!!', '01-block-dynamic' ); ?> | ||
</p> | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
I find this sentence here a little confusing. It sounds like the markup of the block is wrapped by some markup we cannot control.
Which was the case with the
apiVersion: 1
but withapiVersion: 2 & 3
that no longer ist the case and we have theuseBlockProps
hook to get the attributes that need to exist on the wrapper to manually add to our own markup. So a developer has full control over the markup of the block including the wrapperThere 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.
@fabiankaegy I have rephrased that part inspired by the info in your comment.
Let me know what you think