Very early on in my WordPress journey I got a request from a client to customize a specific portion of the wp-admin screen and was introduced to the concept of metaboxes and how you could add your own. Outside of the work I had been doing with themeing and customizing the front end experience of a website, this seemed like a whole new world!
Over the years I've been searching for a way to customize the admin experience that's felt truly native and easy to use. The Block Editor, along with the various Block Editor components has finally been that experience for me.
What is the use case for customizing the admin area?
The need to create additional fields inside the WordPress admin can range from needing to add a single text field to capture a piece of metadata about a particular post, all the way up to a complex set of global configuration options to power an entire site. That's what makes finding the "perfect" solution so difficult.
But essentially, the solution I had always envisioned would allow a developer to:
- Not have to re-invent the wheel and write HTML/CSS for admin components every time a new one is needed
- Have some sane defaults around securely saving this data (escaping and sanitizing) and being able to easily display/use it on the front end.
- Not be a huge effort to make it feel "native". It should look and feel like the rest of the WordPress Dashboard.
With those criteria in mind, and mostly because I didn't know any better at the time, my first foray into customizing the WordPress admin area (back in 2014) was Custom Meta Boxes.
Trying out Custom Meta Boxes
Back when I was first getting started, custom meta boxes were the state of the art way to customize any admin screen. While they definitely addressed my desire to have my customizations look and feel like a native WordPress experience (because that's what the rest of wp-admin was using as well), I quickly found them very difficult to work with.
To get the metabox to show up, you had to call the add_meta_box
function, then you had to write your HTML to render the metabox in a callback (and I had no idea what that was at the time) to get anything to actually show up on the page. And on top of that, you still had to take care of a whole host of other things that I couldn't really wrap my head around. Even the official documentation remarks that the official example code is "not suitable for production environments..." and "Operations such as securing input, user capabilities, nonces, and internationalization have been intentionally omitted. Be sure to always address these important operations."
It seemed like meta boxes were the best approach to take, but as far as using them for client projects, it seemed too time-intensive to spend time creating these admin experiences when working on the frontend display code for the site was much more valuable.
That is until I found Advanced Custom Fields.
Discovering ACF
When I first discovered Advanced Custom Fields (ACF), it felt like exactly what I had been looking for! It utilized the display power of custom meta boxes to make sure my customization looked and felt like something native to WordPress, but also allowed me to not have to worry about writing the HTML to actually make those meta boxes happen.
With the Pro license and access to the Repeater field, I could suddenly create much more complicated and flexible interfaces than before, while writing way less code. For this reason and all the other field types that were available, using ACF to customize all the admin screens on client's sites, add custom options pages and much more was the staple of my development process for many years.
And then, Gutenberg was announced.
Trying to do things the "Gutenberg" way
When the Block Editor was announced and still being referred to as Gutenberg, I took a stab at properly learning React and trying to build out custom blocks using Javascript.
The tooling was so new and there were so many different ways of doing things that it was very difficult to find a consistent tutorial and process to follow. I quickly gave up on this approach to admin customization and was convinced I was going to have to deal with all my ACF metaboxes being pushed below the editor until Advanced Custom Fields announced the support for creating blocks with ACF.
ACF Blocks
And we were back in business! All the ease of using ACF was brought straight into the block editor. The concept of "flipping the block over" to preview it vs flipping it over to edit fields felt a little bit like a second class experience compared to the core blocks where editing content right inside the field was possible. But for most builds that was enough. It allowed me to build admin experiences that did what they needed to do and enabled content creators and editorial teams to leverage the block editor.
However, as I built out more and more ACF blocks, I still found myself wanting a bit more control over 2 specific areas. Firstly, I wanted to be able to create those sort of seamless experiences you get with core blocks, where you can type and configure the block right in the editor and see the results right away.
And the second was the ability to use external data. I had a few requests over the years to query external APIs and associate external data with post content and as far as I know, there's no ACF field that allows you to consume or associate anything outside of WordPress with a piece of WordPress content.
For this second case, I ended up building out something that worked very well with Fieldmanager, which deserves an honorable mention here. But still, for Block Editor-based sites, this was a bit clunky.
So on a recent build, hoping for different results than last time, I decided to give the more "native" way of building blocks a try.
Native Block Editor Components
...and so far it's worked out great! The tooling is much improved, especially with resources like 10up's Gutenberg Training. Much to my surprise, I found that in the intervening 4 years or so, a whole library of components had been built out to power the Block Editor. Because of how React works, when you're building custom blocks, you can also use these components to create complex controls and editor experiences.
To be clear, I'm talking about "dynamic blocks", which use PHP for rendering the block on the frontend, just like you would with ACF! This gives you the benefit of the frontend workflow that you're already used to, while still being able to take care of the pre-built editor components on the backend.
Using Block Components meant that you don't have to reinvent the wheel and write your own custom HTML/CSS for metaboxes. You can leverage the same tools the Core team uses to build the Block Editor for your own custom development. And because they use all the same pathways as the Core controls, the other tangential pieces to building meta boxes like saving content in a safe way are also taken care of for you.
Finally, as far as the ability to leverage outside data and make even more complex admin experiences, since everything is a React component, anything you could do in pure Javascript you could now do inside a block!
For me, this is the perfect combination of feeling native, being relatively easy to use and easy to do right with sane defaults, while still being extremely powerful. If you haven't looked at block development using Javascript in awhile, now definitely feels like the time to give it another try.
I'm very much looking forward to seeing what sorts of interactive blocks I can create that make creating content feel like a much more straightforward and seamless experience.