Tom McFarlin

Software Engineering in WordPress, PHP, and Backend Development

Page 9 of 426

Block Notes: How to Register a Custom Block Category

It’s been a while since I’ve done any custom block development. In fact, the last time I called bankruptcy on any content was when I was writing about building blocks for WordPress.

A bit has changed since then, though:

  • the way in which blocks are developed has improved,
  • and I’ve finally gotten a little more experience.

That said, there are still things that are less familiar since I spend more of my time working predominately with PHP, WordPress-adjacent tools, and custom plugins, too.

But I think it’s worth sharing a few notes that I’ve picked up if or no other reason than I can refer back to them in the future. So for the first note in these “block notes,” here’s what has to be done if you want to register a a custom block category for any custom blocks you’re building.


In the screenshot below, you’ll notice under the Blocks tab, you can see categories such as Text and Media:

But if you’re working on a set of custom blocks that don’t fit into these categories or that should belong to a category of their own, this is how you set it up your plugin to accomodate.

For the sake of example, let’s create a custom categories called Acme Company.

First, leverage the block_categories_all filter.

Filters the default array of categories for block types.

In the plugin bootstrap, you can add the code like this:

Notice in the code above, we’re creating a category called Acme Category. This is what will show up in the side back of the available blocks whenever we begin registering our own blocks.

And now, across the various JavaScript files in which blocks are registered, we add the category property whenever we call registerBlockType.

Registers a block type. The recommended way is to register a block type using the metadata stored in the block.json file.

For what it’s worth, I haven’t used a block.json file (at least note yet); but I do use registerBlockType in the JavaScript source in which the block file is created. For example:

Source code of how to add a custom category to a custom block that's created with the "register block type" function.

Now anytime a block is registered and includes this category, the block will appear alongside any and every block that all under the same category.

This can be useful whenever you’re trying to a build a library of related blocks, or if you’re ultimately going to be working with blocks that work with each other.

And I’ll cover this case in a future note.

One Way to Standardize Structure for Must-Use Plugins

The mu-plugins directory can often become full of various files that have basically been dropped in to solve a particular problem for the particular WordPress installation.

In my experience, these are often useful plugins but they aren’t structured like more standard plugins. That is, mu-plugins often look like a bunch of files dropped in the directory that don’t make a lot of sense unless you read the files. Further, an mu-plugin is often a single file that’s monolithic in nature.

Given the nature of mu-plugins, there’s a case to be made they shouldn’t need to be structured like that. Of course, if you’re building some advanced functionality that is considered must-use, then I think it’s worth building it in such a way that follows modern standards and still works within the mu-plugins structure.

What options are there, though?


I’m sure there are many solutions for how to do this but the way that I’ve found to be cleanest while also allowing me to build plugins in the way I typically do is to maintain a bootstrap file in the mu-plugins directory that references the actual plugin which resides in its own subdirectory.

For example, let’s say I’m building a plugin called acme-solution and the basic file structure looks like something like this:

To drop this into the mu-plugins directory, it’s far too many files as it makes it difficult to maintain along with the rest of the plugins that are present (not to mention the work that may be required when working with a CI/CD app).

So then, I’ll create a bootstrap that looks like this

This obviously is named the same as the acme-solution subdirectory to keep cohesion as high as possible. Then the plugin that resides in acme-solution is structure the same as if it were a standard alone plugin.

And, for what it’s worth, the GitHub repository is structure exactly as you see here. That is:

  • CHANGELOG.md
  • README.md
  • LICENSE
  • composer.json
  • composer.lock
  • src/
  • vendor/

Are included in the repository as well.


Note

  • The vendor directory usually only includes the autoloader. I don’t recommend checking all of the dependencies into the repository unless there’s a good reason to do so.
  • Props to Benjamin Rojas for working with me on coming up with something that’s applicable across a variety of types of mu-plugins.

Why We Don’t Always Need Do Perform an Early Return

There are a lot of opinions on how return statements should work.

  • Some say that there should be a single point of return in a function,
  • Some day we should return as early as possible,
  • Some day multiple return statements are fine,
  • And some say that, when applicable, return as early as possible.

I’m sure I’m missing some, but all of these are ones I’m sure the majority of you have seen. And though I don’t hold either of these to be law, I think there’s a time and a place for each.


I’m a fan of the early return statement. In my mind, the sooner we can determine we don’t need to do the work of a function, the better we just leave.

For example, say we know if we’re not on a certain page, we can go ahead and leave the function:

In this case, it makes sense because:

  1. You only want to perform work on the plugins.php page,
  2. The amount of work to be done in the function is larger than what should ever fit within a conditional.

But there’s an alternative when the amount of work is less than what’s above.

Continue reading

The Term ‘WordPress Adjacent’ Should Be More Precise

Over the last year or so, the term “WordPress adjacent” has become more popular to use. And I get it. There are a lot of us who are still heavily involved with WordPress but who are building tools and/or solutions that may not only interact with WordPress or that start with WordPress and fan out from there.

So that phrase, as they say, has entered the chat. And it’s not a bad phrase, per se. But I think it’s imprecise and I think we can do better. This is important for those of us who write, podcast, speak, and any or all of the above.

This is you, entering the chat. Photo Credit.

First because I believe it’s important for us to be able to clearly define about what we’re talking and how it relates to WordPress. And secondly, so that our audience can follow it.

Imagine thinking you’re going to hear someone talk about building headless applications in WordPress and all that comes with that only to hear that a backend engineer is going to be talking about building a utility that incorporates Google Cloud Functions and custom endpoints to send data to a cloud-based database and to a WordPress database, too.

All of that falls under the umbrella of WordPress Adjacent. And that’s why it’s not good enough. It’s why we need to more more precise.

What Does It Mean to Be WordPress Adjacent?

Starting a more broadly, I would say, at it’s core, being WordPress adjacent refers to individuals or projects closely associated with WordPress, either through direct use or integration with technologies related to the core application.

It’s straightforward enough, but it’s a mouthful, isn’t it? Trying to throw this into a presentation or a podcast and you’re going to lose half your audience.

This person just checked out of your talk. Photo Credit.

Here’s why I say that: In their mind, people already have what it means to be WordPress adjacent. So when what you describe doesn’t map to what they think, it feels like someone is wrong or perhaps being misunderstood.

There’s no reason to feel that way but this is why I think we need a level of precision. Ultimately, there’s a myriad of ways one can be WordPress adjacent.

Lack of Precision is Frustrating (Why Wouldn’t It Be?)

The imprecision of the term WordPress adjacent is both a blessing and a curse. On one hand, it allows for flexibility, acknowledging the diverse roles and projects within the WordPress ecosystem.

On the other, this vagueness can lead to confusion. Imagine trying to explain your job to someone using this term – chances are, you’d end up providing a convoluted explanation that leaves the them more confused than not.

Okay, so How Do We Address It?

In my experience backend engineer, I’ve found myself involved in projects that are WordPress adjacent. And there’s certainly been an uptick in that in the last few years. Further, I’m grateful for it because it allows me to continue to grow as an engineer with learning other technologies, integrating them, and then having them still communicate with WordPress.

Case in point. Imagine, databases with a master and development branches all accessible via PHP or cloud functions.

From developing custom APIs that communicate seamlessly with WordPress installations to creating data systems all of which ultimately increase the functionality of WordPress websites.

Stuff like this orbits WordPress without directly living only within it.

And so that’s how what I do is WordPress adjacent. It may be how the work you do is too. But it’s not the same for all of us.

Clarifying Our Roles

So, how do we address this ambiguity? When we use the term “WordPress adjacent,” we provide a brief explanation of how exactly we are adjacent. Whether it’s through

  • developing plugins,
  • creating bespoke themes,
  • enhancing user experience,
  • building headless front-ends,
  • communicating with third-party APIs and integrating them back into the WordPress application (or vice versa),
  • and so on.

Specifying our roles helps in demystifying the term for others.

Ultimately, it fosters a deeper understanding of the diverse economy that revolves around WordPress.

Clearing Things Up

In technology, clarity is key. And given WordPress is technology, it isn’t exempt from that.

For those of us who work in this space, we have a responsibility to those who read our articles, listen to our podcasts, or attend our talks to clarify our roles. Don’t leave it to them to figure out in the moment.

If you’re going to be using the term in the future – which I personally hope to see more of – let’s at least explain how we’re adjacent.

Use Custom Functions to Determine Which Environment You’re Running Your Code

WordPress provides constants and functions for setting up and checking to see if we’re in development mode.

Specifically, see the following:

But if you’re in a situation in which you’re working on code that’s, say, WordPress-adjacent where it both talks to third-party APIs and services but also sends data to WordPress (or reads data from WordPress), it may be helpful to have another way to determine if your code is running on a local machine.

Use Custom Functions

Case in Point

Perhaps you’re going to be registering a JavaScript file that requires a dependencies that is not available on your local machine. If this is the case, you have a few options:

  1. Find all of the dependencies from the production application and add them to your local machine ignoring whatever side effects may happen,
  2. Remove a call to the dependencies in your code and try to remember to add it back before committing to source code,
  3. Or use a a drop-in function for checking if you’re running the code locally.

Though I know each option has its own tradeoffs, I find myself doing the third option more often than not. All it requires is evaluating the loopback interface and seeing where the script is running.

In the context of PHP, a loopback interface refers to the ability of a script or a server to send requests to itself. So if you check to see if it’s running on 127.0.0.1, which is an IPv4 variation of localhost or ::1 which is the IPv6 variation of localhost then you can determine how to move foward.

A Simple Example

Here’s my example function:

public function isLocalDevelopmentEnvironment()
{
    return (
        0 === strcasecmp('::1', $_SERVER['REMOTE_ADDR']) ||
        0 === strcasecmp('127.0.0.1', $_SERVER['REMOTE_ADDR'])
    );
}

Then if you want to use this when, say, enqueuing JavaScript sources in WordPress, you can set up a conditional for dependencies like this:

$dependencies = ['jquery', 'acme-scripts'];
if ($this->isLocalDevelopmentEnvironment()) {
    $dependencies = ['jquery'];
}

Then you can enqueue the scripts like this:

wp_enqueue_script(
    'acme',
    $this->jsDir . 'omega.js',
    $dependencies,
    \filemtime(__FILE__),
    true
);

Sure, it’s a simple example but there’s much more that can be done with that single helper function regardless of if you’re working with WordPress, Google Cloud Functions, cloud databases, or more.

There are, of course, much more complicated ways in which custom functions can be written and used. The point isn’t about complexity, though. It’s about thinking through when utility functions like this are helpful and when they should be used.

« Older posts Newer posts »

© 2025 Tom McFarlin

Theme by Anders NorenUp ↑