Single Blog

Failure and Learning: My Experience Building 4 Block Plugins in a Week

I built four block plugins last week. It was not something I had set out to do. I did not wake up one day and declare, “I think I will build a suite of custom block types over the next few days.” It just happened.

The first plugin I built was to address an old ticket for Gutenberg that had not seen any traction. Perhaps others were not interested in the idea, or it never crossed their path in the sea of 1,000s of other tickets. Why not just build it myself? So, I did. It took a couple of hours, but much of that time was re-configuring the @wordpress/scripts build script to my liking and reading docs.

With that plugin out of the way, I started seeking new problems to solve. One that was already on my radar was the missing Comments Title block necessary to bring the upcoming Comments Query Loop block to feature parity before WordPress 6.0 lands. So, I built a rough plugin for it.

WordPress site editor with a Comments Query Loop inserted.  At the top, a Comments Title block is highlighted.
Comments Title block in the site editor.

Fortunately, others took that initial idea and ran with it, building something far more flexible than my first attempt. Now, there is a new block in Gutenberg.

I had a couple of other itches I wanted to scratch, and there was little to do on a rain-filled Sunday. Namely, WordPress does not include equivalent blocks for the wp_list_users() and wp_list_authors() template tags. That seemed like an oversight, so I tackled early versions of those.

I will put these up for free on the official WordPress plugin directory soon for folks interested in them. I can only hope they will help someone else in the future.

This post is about sharing my experience, the journey, rather than what became of it all.

Recently, someone asked whether I could operate in this JavaScript-heavy world of blocks as a developer. It has been over two years since I took on a writing position here at WP Tavern and developed real-world solutions for users. I was only starting to use JavaScript with the block editor back then.

Since then, I have dabbled with block themes, even releasing one on WordPress.org. I have built a few PHP-based projects for fun in my spare time. I even created my first custom block plugin last summer and shared my experience with readers. Shortly after, I built a second.

That burning flame I had nearly a year ago quickly died down. That had more to do with the state of block theme development, which was still in its infancy, than anything. I was excited about its potential, but consistent breakage was more than I had time to deal with, considering all of it was a fun side project.

At heart, I am still a programmer, a problem solver. So, I began anew.

The first stop was the JavaScript Build Setup documentation for building blocks. I was going to learn the “WordPress way” this time around. For the most part, I followed through with that.

The only hiccup I had was the setup script snake-casing my namespace, x3p0, into x_3_p_0 in function names. That was a mess to clean up. However, I did not need to go through that process in other block plugins. I just wanted the beginner experience on the first go.

For building blocks, @wordpress/scripts is all that is necessary. I tinkered with it, added a couple of custom commands, and modified the input/output folders. However, it has everything needed to get up and running fast.

I skipped past the Hola, mundo! (Hello, world!) portion of the setup tutorial. Whenever I set out to build anything, I plan to dive headfirst into something a bit more complex. However, it never hurts to get the basics down to see how things work.

My style of programming is one built upon failure. I venture out with an idea, fail miserably, and continue learning from my mistakes. A short while later, I had a custom block type that showed a link back to a nested comment’s parent:

WordPress site editor showing a Comments Query Loop with two comments.  A block reading "in reply to Comment Author" is highlighted.
Comment parent link block.

While that was a success, I have learned that some other built-in editor components might make it even better.

That first block gave me a taste of modern development on WordPress. It was a relatively simple plugin to build, but it was easy to see how one could expand it out to more complex features.

The components system has grown into a robust and flexible toolset for developers over these last few years. Plus, the component-level documentation is well-rounded at this point, especially when pairing it with usage in the core code.

As I continued building new blocks, I started taking on more complex concepts. One of the things I needed to learn was how to interact with the core data layer. As I stepped into my third and fourth block types, I needed to query users and list them:

WordPress post editor with a custom-built Authors block that lists users with posts.
Listing users via an Authors block.

While there is a “basics” tutorial on working with core data, the reference guide was spotty in places. Some pieces even seemed to be missing altogether. Where were the advanced guides? I could not find any, and “doing stuff” with data is the meat of plugin development when you get beyond a few simple form fields.

I spent some time with the tried and true console.log() to figure out things and perused the core code. Eventually, I pushed through and built a couple of working projects.

Did my experience improve this time around compared to a year ago? Without a doubt, it did.

More than anything, I want to thank all the contributors to the Gutenberg project. The build tools and range of pre-built components are welcome for this developer who has spent most of his time in the PHP world. I always enjoy being able to pick up a toolset and start building with it right away. I am sure I have only glimpsed some of what is possible at this point, but I look forward to trying new things. As I grow more comfortable, maybe I will write some of those advanced tutorials that I believe are missing.