Site icon Karen Attfield

Extending a WordPress block

Markers pinned on a globe map of the world

Markers added to a world map globe

I wanted to try extending an existing block from another plugin. As I didn’t have a fantastic idea of what to extend I simply extended the Jetpack Map block to allow the ability to add clickable links within marker captions. That wasn’t my first choice though – I quickly realized that I was limited in customizability, depending on the block functionality itself.

For example, one idea I had originally was to add an option to upload GPX tracks to a Jetpack map. However that would have required direct map modification, beyond just manipulating existing attributes or adding new attributes. The problem with adding new attributes in this case is that I wouldn’t have been able to use them to change how the Jetpack map block interacted with the map provider – Mapbox – itself.

So, caption links was what was chosen. I added the code for this new plugin here on Github, so instead of sharing the full code below I’ll focus briefly on the main take-aways from my own experience.

Plugin boilerplate

For the plugin set-up, I use the WordPress Plugin Boilerplate template, and I use wp-env for the local environment set-up.

When to use registerBlockVariations

One assumption I made is that if I’m extending a block plugin, I’ll need to use the block variations API. That wasn’t true.

Block variations are useful if you want to offer users a distinct configuration or preset version of a block. But if you’re simply adding inspector controls, attributes, or extending functionality of an existing block, it’s not required.

So basically, if I wanted a separate block that users could choose because it’s preset versions are what they’d prefer to use, I’d create a variation. In my case, I wanted to add inspector controls to the existing map block to allow for customized caption links, so could just add this to the existing Jetpack Map block.

As a user then, the difference is that in the block selector I select the Jetpack Map block and if the extension plugin is also active then its changes will be part of what I see when customizing the Jetpack Block. If I had a block variation, then in the block selector I could choose between the unmodified Jetpack Map block, or the new customized block.

What about differences in saved attributes?

To slightly go against what I just mentioned above, there is another scenario where you’d be better off using a block variation: when you are adding new attributes to be sent to the front-end, and you may find yourself in a situation where newly-generated markup does not match what was previously stored in post content, a scenario which would result in the block being marked as invalid.

To explain more, when adding attributes to a block using the blocks.getSaveContent.extraProps filter (more info on that filter here), the attributes are stored in the block markup.

When we then consider a previously added versions of the original block (which won’t include this attribute in their markup), when the new extension plugin is activated and modifies the block’s saved attributes, WordPress cannot reconcile the differences between the existing saved content and the new definitions expected by the extended block.

Also, if modifying saved content, you’ll need to make sure you have a good way to clean that up on deactivation of your plugin, without breaking the existing block.

What are the options?

You could add a deprecation in your own plugin – but the moment the original block that you’ve extended has attribute changes and it’s own deprecations, then your block will be broken, so that’s also not ideal. This also doesn’t consider what happens when your plugin is deactivated.

A better option then is to use the PHP block filter – render_block. This is the recommended approach to modify the existing content server-side.

If you registered a block variation, it will have its own saved markup and attributes. This means if a user has the original unextended block that was saved without your additional attributes, activating your variation won’t cause issues because it won’t modify the existing content. Also, existing blocks won’t be affected by new variations. And if your plugin is deactivated, your version of the block is removed.

What would I recommend?

It does really depend on what you are trying to achieve, there are many possibilities in terms of what you might want to extend. But in my test case, most of the functionality was in the editor – providing a way to add links to map marker captions. I did want to pass the link color on to the front-end though via the block attributes, and thought that a cleaner way to do that would be to add a new attribute to the rendered block with the caption link color. I found that render_block was best for that.

Here is the plugin I created to extend the Jetpack Map block by allowing for color-customized clickable marker caption links, if you’d like to take a look.

Exit mobile version