Software Engineering in WordPress, PHP, and Backend Development

Tag: WordPress (Page 3 of 219)

Articles, tips, and resources for WordPress-based development.

Thoughts on the Upcoming WordPress Admin Redesign

During this year’s State of the Word, the new design for the WordPress administration experience was discussed.

As described by Matias:

As WordPress turns twenty years old, the overall aim of this work is to improve upon this experience at a foundational design level, giving plugins and users more control over the navigation while ensuring each WordPress experience is recognizable, intuitive, accessible, and delightful.

The full posts lays out the high-level plans for how they plan to move forward and I find the Scope section one that’s most relevant for developers (and designers who write code, as well).

This dude is completely stoked about the redesign.

It’s too long – and redundant – to post here, so I recommend reading it via the aforementioned link.


The Upcoming WordPress Admin Redesign

As a developer who’s worked in this space since “The Kubrick Era” (is that even the way some people refer to it?) and has been involved through the years of Gutenberg development, I have some thoughts relevant to the announcement that I’m sharing for posterity to see how things pan out as this project begins.

  • I was a fan of the UI refresh we received a few years ago and I’m excited about what’s planned for this one, as well. It feels like it’s going to be much bigger but it’s easier to say that when we’ve been working with the current UI for so long (and I remember the design before that – it was no small undertaking to update it, either).
  • I’m looking forward to seeing how hooks are going to be updated (and if anything new will be introduced in terms of what we’re able to do within the admin). Will be using JavaScript to work with them more? How does PHP fit into this?
  • I’m curious as to how other things have not been updated in some time (such as certain Settings screens) will be updated beyond revamping the UI. That is, part of the WordPress philosophy used to be decisions, not options but I’d say the software isn’t as decisive as it could (or should?) be. My guess is most of the options are going to stay the same, but the general look and feel is what will change.
  • I hope to see clear documentation provided for each release for developers, designers, and users to help make it clear how to achieve certain tasks. That was a challenge within the Gutenberg-era – things that worked in one release didn’t worked in a new release and the cycle was happening to fast, it was difficult to keep up.
  • I’m very interested to see how plugins will inherently interact with the new UI given many are built to perform, look, and feel native within the existing UI.
  • Performance is something that’s always a concern and if you’ve done any profiling or network monitoring within the tools the Chromium-based browsers provide, it’s evident that there’s some things that could be refactored. Is now the time? (I’m genuinely asking – this isn’t a loaded question.)
  • I’m curious to see how well the existing Block Editor will fit within the context of the new experience. Will anything need to be modified, adjusted, or tweaked to make it feel more natural or is the Block Editor, as we know it today, more-or-less standardized?

But that’s not all there is to say about it. A lot is going into the overall project especially given this is just the third phase of a larger roadmap.


Change Is Hard

As the cliché goes, change is hard. But working through change when there are so many opinions on how the change is going makes it ever harder. Further, all the training material that agencies and organizations have as well as the material they will produce are eventually going to need to be updated as the new administration area is released.

Not that kind of change. Though I guess it’s technically hard, too.

I know the ultimate goal is to have more modern administration experience that’s easier for all types of users and I’m excited to see it come to fruition.

There’s likely going to be some friction – as is the case to come with any major updates – but I’m optimistic that we’ve learned a lot from how Gutenberg was initially developed and rolled out and I hope to see others work even more closely with the administration experience to make the transition easier both for developers and users.

I Didn’t Want to Resist Gutenberg

Though I wouldn’t say I resisted Gutenberg, I definitely found plenty of times where wasn’t ready for how I wanted to use it. The learning curve was forever influx because of the how the underlying technologies were changing or how the implementation of those technologies were changing.

Dude’s as scared of this printer as some were of Gutenberg.

To put it succinctly, trying to adopt it into my day-to-day work was a challenge.

Thus, it made me slower to adopt it both as a user and as a developer until it reached a certain level. Now it’s stabilized to a point where I both enjoy writing with it and have learned enough of the APIs to build out custom blocks for my day-to-day work in a consistent way (yes, even as one of those old people who primary works with server-side technologies).

I Don’t Want to Resist the Admin Redesign

To that end, though I recognize there are going to be inevitable hurdles to cross for this update, I also think this is a time in which lessons learned over the past few years can be applied.

Maybe we’ll receive the new admin like this. This computer is hugging back with a hand of its own.

Even though it’s not a one-to-one comparison, overhauling a major component of an older piece of software once yields plenty of learning. And I hope to be more present at least in terms of making sure the things developers enjoy – such as certain actions, filters, and other things with regard to menus, settings pages, options, and so on – are easy to learn and make sense when it comes time to migrate our code.

How To Mitigate Side Effects in WordPress Development

In software development, the concept of a side effect is generally understood to be something like this:

In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, which is to say if it has any observable effect other than its primary effect of returning a value to the invoker of the operation.

Side effect, Wikipedia

The Software Engineering Stack Exchange has a great answer. You can read it in its entirety, but I really like how succinct the person puts it:

It’s really very simple. Side effect = changing something somewhere.

There are a handful of ways developers try to mitigate side effects such as automated testing or quality assurance, but when a piece of software is large enough such that each part that composes the system is like a small system unto itself, it’s not difficult to imagine how introducing new code could inadvertently change the state of the program.

This is why any given project at scale is impressive to see work as smoothly as it does. (Sure, projects like large scale web applications, operating systems, are one thing but thinking about medical software, automotive software, the software that runs on airplanes, applications built at places such as NASA, and so on are all the more amazing.)


Bringing this down to the level of stuff I write about and that I work on during my day-to-day – specifically WordPress – side effects are something we’re likely all too familiar with experiencing.

If nothing else, think about the last time you activated a plugin and it immediately conflicted with another plugin or a feature of theme.

  • It could have thrown up a notice,
  • It might have displayed an error message,
  • Perhaps it completely broke the way some part of the way the core application functions,
  • Or it just threw up a PHP error message that wasn’t even clear on what was going on.

To make matters even more fun, the only way to resolve the issue is the disable the plugin via WP CLI or, even more drastic, deleting the plugin.

This is an obvious example of a side effect in WordPress. They can happen for any number reasons, too. Sometimes it’s a matter of running a different version of PHP, it could be a matter of a team not keeping their code contained in its own namespace, or perhaps it’s a matter of not doing enough testing.

Regardless of the case, it’s something many of us have experienced and it’s likely a problem many of us have caused during our careers.

Initially, when I started thinking about side effects in WordPress development, I was working on a plugin that needed to fire when certain events happen during the user management lifecycle.

From there, I started thinking about edge cases and then I started thinking about the overall economy around WordPress and the interoperability and compatibility challenges that come with writing software that runs on top of a piece of open source software that powers so much of the web.

It’s impressive.

Then I was left at a fork of what I wanted to discuss:

  1. Should I talk about the initial problem that kicked off this entire post (that is, making sure I handled all cases of user management)?
  2. Or should I offer general commentary on edge cases and how it relates to work in building WordPress or WordPress adjacent projects?

If you’ve read this far, it’s obvious that I’ve spent more time on the latter than the former. So I’ll save the former for another day.

Since I’ve discussed this at length already, these are a few things – in no specific order – I recommend doing the following things to prevent side effects and conflicts when working on WordPress-specific code:

  • Even if you’re not using object-oriented programming, use namespaces to keep all of your functions contained within their own context.
  • Know the environment(s) in which you’re code is going to run and write for the lowest supported version.
  • When writing a custom function that will fire on a specific hook, take the time to understand the priority and number of arguments the function will expect and write your code defensively (that is, ask “how would I write this code so someone else’s won’t interfere with what I’m trying to do?”)
  • Don’t be afraid of writing unit tests not only to ensure your code is doing what it’s supposed to do but also that it’s not doing anything it shouldn’t be doing.
  • Before writing anything to any type of storage, make sure that the keys you’re using are not already in use and/or make sure to uniquely prefix the keys you’re going to use.
  • Don’t add frontend assets to any page that doesn’t need them.

I don’t know if it’s possible to put together and exhaustive list. But in my experience, these are the things that I’ve found to be helpful especially as it relates to working on backend development.

Asynchronous Methods and Headers: Just Working Isn’t Good Enough

When sending asynchronous requests to a WordPress back-end, which may be a REST API or an Ajax callback, it’s helpful to know what headers to specify when sending said data.

Since I recently shared another post about idempotency in REST API design and since asynchronous calls are more common than they have been in the past, I thought it useful to share when to use what type of headers when making said requests.

If you’re working with WordPress in some capacity – be it a headless state or working on processing Ajax calls – then it’s useful indicate how your data is being sent and in what format the data is being sent. Ultimately, your asynchronous methods and headers need to do more than just work.

That is, it’s not enough for it to simply be sent and received. Instead, the data should be sent in a format congruent with what the backend service expects. If anything, future you will thank you. To make it even more relevant, this is an opportunity to keep our code as clean as possible.


Asynchronous Methods and Headers

When creating an Ajax request in WordPress using modern, vanilla JavaScript the request will likely look something like this:

fetch(tmAcmePlugin.ajaxurl, {
    method: 'POST',
    body: data,
    credentials: 'same-origin',
    headers: new Headers({
        'Content-Type': 'application/json',
    }),
})

Notice here I’m specifying the headers as part of the request which isn’t something we’ve historically done. In this example, I’m using application/json.

It’s also common to send form data across the wire, too. And if you do that, then your request will look something like this:

fetch(tmAcmePlugin.ajaxurl, {
    method: 'POST',
    body: data,
    credentials: 'same-origin',
    headers: new Headers({
        'Content-Type': 'application/x-www-form-urlencoded',
    }),
})

Obviously, know which type of header to send and when is important. As obvious as it seems, these are the guidelines I recommend when working in the context of WordPress-centric applications.

  • Use application/json whenever you’re sending a payload that’s structured as JSON. Whenever you’re receiving the data on the server, you’ll need to use json_decode or your language’s equivalent to parse the data.
  • Use application/x-www-form-urlencoded whenever you’re sending a payload that comes from data being sent from a form element or in a string of key/value pairs such as key_one=value_one&key_two=value_two. Typically, this will be received in a POST request.

Again, however you specify the method and the header, the data will still be sent but how you manage it on the server may not match up to what’s expected.


If someone else – either someone with whom you work or just future you – reads the client-side code and the server-side code and what’s sent doesn’t match, it’s going to create an entire set of circumstances of detangling what’s been done and something that’s completely unavoidable.

Block Notes: Generate a Reference to a Block

I’m working on a block that, like many, isn’t limited to a single instance in the editor (and thus not the frontend); however, because there are certain features of the block I want to manipulate when the page loads, I want generate a reference to said block.

For example, the structure of the markup in the edit function looks something like this:

<div className="wp-acme-block">
  <div className="wp-acme-block-editor">
  </div>
  <div className="wp-acme-block-preview">
  </div>
</div>

The functionality will allow the user to toggle the visibility of the editor container and the preview container. And to manage this functionality, I want to access the parent element of each one. Specifically, the one with the class wp-acme-block.


And this is easy to do with a couple of features of React:

  • useRef is a hook that allows for direct interaction with the DOM. It returns a ref object that maintains a property called current. This enables us to maintain a reference to a specific element.
  • useEffect is a hook that handles side effects in functional components. It allows us to do a lot of things (like fetching data) but also allows us to manually work with the DOM.

Given those two hooks, I can place a ref attribute on the primary container that I can then use elsewhere in the code.

First, in the header of the file add the following:

import { useRef, useEffect } from 'react';

Then at the top of the edit function, I have the following code:

edit: ({ attributes, setAttributes }) => {
    const blockRef = useRef(null);
    // ...
};

Then, in the edit function where I have the markup that I’ve shown above, I’ll add the ref attribute:

<div className="wp-acme-block" ref={blockRef}>
  <div className="wp-acme-block-editor">
  </div>
  <div className="wp-acme-block-preview">
  </div>
</div>

And finally, I can use this reference in the edit function before it calls return so I can refer to the element in other functions.

useEffect(() => {
  acmePreviewFunction(blockRef.current);
}, []);

So the full, relevant code looks like this:

import { useRef, useEffect } from 'react';

// ...

registerBlockType('acme/example-block', {
  // ...

  attributes: {
    // ...
  },
  edit: ({ attributes, setAttributes }) => {
    const blockRef = useRef(null);

    // ...

    useEffect(() => {
      acmePreviewFunction(blockRef.current);
    }, []);

    // ...

    return (
      <div className="wp-acme-block" ref={blockRef}>
        <div className="wp-acme-block-editor">
        </div>
        <div className="wp-acme-block-preview">
        </div>
      </div>
    );
  },
  // ...
});

Then passing the current property as an argument to other functions, you’ve got access to the block such that you can manipulate it with other JavaScript functions.

Further, the ref will refer only to the instance of the block so it won’t manipulate other instances of the block located in the editor (or, more specifically, the DOM).

Block Notes: How To Nest Related Blocks

When creating a custom category into which you want to group your own blocks, you may also want to create a block that can only hold blocks that belong to that group. Or, in other words, you may want to create a block that can nest related blocks.

For example, in the last post, I showed how to create a custom category into which blocks can be grouped. And that works well when you can want to create a group for related blocks.

This can be taken a step further, though. Say you want to create a custom block that can only hold blocks that are part of your custom category.


The primarily things that need to be done to achieve this are:

  1. Make sure the block you’re creating is also part of the same custom category.
  2. In the supports attribute, specifically list the blocks the block in question will allow.

The edit and save functions don’t need to be particularly fancy for this unless you want to achieve something more.

First, the attributes section of your block may look something like this:

Notice here it has the standard title, icon, and category all blocks have (and the category matches what was outlined previously. Now add an allowedBlocks array to the supports attribute. This is where you can restrict the blocks that can be contained within this block.

The important thing to note is that you know the namespace and name of the blocks (these are of the format namespace/block-name and are usually was you find when calling registerBlockType.

Finally, in the edit function, add this attribute to the InnerBlocks components. From the component in the GitHub repository:

InnerBlocks exports a pair of components which can be used in block implementations to enable nested block content.

The code for edit can, out of the box, look like this:

And the save function looks like this:

Finally, once you’ve done all of this and rebuilt the assets, then the block panel within the editor should yield something that looks like this:

And that’s it.


As mentioned earlier, you can see edit and save are simple. It’s possible to make them as elaborate as needed, but if you’re just building a container to support your custom blocks, this is all you need.

« Older posts Newer posts »

© 2025 Tom McFarlin

Theme by Anders NorenUp ↑