One of the benefits of building blocks is the ability to allow users to control the block's
appearance and behavior via block attributes. Let's learn how to add attributes to a block
and how to add controls to your block to allow users to change those attributes.
Attributes are the properties of the block that can be controlled by the user. For example,
for the copyright date block, the starting year would be an attribute that the user can change.
To add attributes to a block, you define them in the blocks metadata in the block.json file.
Open the block.json file and then add the following code.
Attributes starting year
find a type
and let's set a default.
One of the benefits of the JSON format is that you can add a new property anywhere in the existing
JSON object as long as you use a property name that is expected. In this case, the attributes
property is expected by the block registration process, so you can add it anywhere in the JSON
object. In this example, you've added an attribute called starting year to the block.
The type property defines the data type of the attribute and the default property sets its
initial value. If you were running the node development server, you might notice that it
crashes when you edit the block metadata. If this happens, just restart the server.
To access the block attributes in the blocks edit component, you can specify a props argument in the
edit component function. Both the edit component and the save function are set up to always accept
this props object containing all the properties of the block. You can then access the blocks
attributes with the props object. For example, to access the starting year attribute, you would use
props attributes starting year. And you could then replace the starting year with that variable.
You can also update the save function to include and use the block attribute.
So props
starting year props attributes starting year
starting year
instead of writing out props attributes starting year every time you want to access the starting
year attribute, you can use something called the destructuring assignment syntax to extract the
attributes from the props object. And then again to extract the starting year from the attributes.
So this becomes
attributes
and this becomes
starting year attributes. And then let's update the save JS in the same way. So use the curly
braces, destruct attributes. And then we can simply copy this code over here.
If you're new to object destructuring, it's a way to extract properties from an object
and assign them to variables. It does seem a little strange at first, but once you get used to it,
it saves a lot of time and code. Let the build process complete, then add the block to a postal
page. And you'll see that the block now displays the starting year attributes with the default
value you defined. If you happen to be testing your block in a postal page and refreshing your
browser each time you make changes to the block attributes default value or the save function,
you might sometimes run into this error. This block contains unexpected or invalid content.
This is because when a block save function is run, it compares the output from the save function
with the output already saved in the database. If they are different, it shows this error.
If you open the console tab of your browser's developer tools, you'll see this reported as a
block validation error. You can fix this by using the attempt block recovery button,
which re renders the block and resaves its output. To allow users to change a block's attributes,
you need to make use of block controls. There are two ways to add controls, either in the
block toolbar that appears above the block when it's selected or in the settings sidebar, also
known as the inspector, which appears in the sidebar when the block is selected. Because
the starting year attribute is a text string, you can add a text control to the block sidebar
to allow users to change the starting year. Add controls to the block sidebar for your block.
You're first going to need to import a few things. You'll need the inspector controls component from
the WordPress block editor package, and you'll need the panel body and text control components
from the WordPress components package. Start by adding these imports to the top of your edit
component. If it's not already open, open the edit.js file in the source directory and look for the
line that imports use block props. The inspector controls component can also be imported from the
WordPress block editor package in the same way. The panel body and text controls components can
be imported from the WordPress components package. So import panel body and text control
from WordPress components. You can now use these components to add controls to the block sidebar.
Start by adding the inspector controls component to the output of the edit component.
This component is a wrapper for all the controls that appear in the block sidebar.
So just above the block output, we can add inspector controls,
then add a panel body component and give it a title attribute.
And we'll just put some text inside the panel body. In the building your first block lesson,
you will remember that a React component can only return a single parent container.
Right now, you don't have a single parent container because you've added the inspector
controls component next to the paragraph component. This is also a reason that your IDE
might start showing you that the code has a problem with all the red warning marks.
At this stage, you have two options. You could update the edit component to render a parent div
tag, moving the block props from the paragraph to the parent div. Alternatively, you could use a
React fragment to wrap everything in a single parent container. Because the functionality of
the block only really requires the paragraph tag output, using a fragment in this way is the best
option in this case. If your block required more markup, like a header tag above the paragraph,
then using the div option might make more sense. Once the build process is finished, if you add
the block to a post or page and either enable the settings sidebar or click on the block if the
sidebar is enabled, you'll see the settings panel that you added to the sidebar. To follow WordPress
plugin development practices, one small update you might want to make is to use the double underscore
translation function to translate the title of the panel body component.
With the settings panel in place, you can now add a text control component to allow the user to
edit the attribute. The text control component is a text input field that allows the user to enter a
string. There are three properties you need to set on the text control component. The first two
are the label and the value. The label appears above the input field.
The value is the value of the field.
The other property that you need to set is the unchange property.
This property is a function that is called when the value of the input field changes,
which receives a new value entered by the user.
This function is then used to update the block starting your attribute.
The syntax of this function might be a little different to what you've seen before.
This is an example of an arrow function syntax, which is a more compact way of
writing functions in JavaScript. In order to update the attribute, you can use one of the
other properties on the props object that is passed to the edit component, the set attributes
function. This function is used to update any block attributes with a new value. You can add
set attributes to the list of properties being destructed from the props object and then use
it to update the starting year attribute. Here we add set attributes and then inside the unchange
function, you can call set attributes and pass in an object with the attribute name
and its new value. And again, the other thing that you might want to change here
is to use the double underscore translation string on the label.
Let the bulk process complete and then add the block to a postal page.
You'll see that you can now change the starting year in the block sidebar
and it automatically updates in real time. You can also switch the block editor to the
code editor view and you'll see the starting year value stored as a JSON object on the block wrapper.
Finally, if you preview the block, it uses the new value of the starting year attribute.
For further reading on these topics, make sure to check out the attributes guide
in the block editor handbook.