Writing a Modern WordPress Plugin

The challenges of learning how to create blocks, text links, and image links in a custom WordPress plugin.

If you’ve been reading along, you know how I recently updated WordPress and found that a custom plugin I wrote several years ago is now grossly out of date.

It’s broken.

When I tried to update the software I needed to revise my plugin I found that my computer, a Mac, is also grossly out of date. I shared all of the trials and tribulations I went through to get a stable development environment last time.

Here I’m going to share the same in regards to updating my custom WordPress plugin.

My Original WordPress Plugin

I wrote the plugin just after WordPress launched it’s Gutenberg blocks concept at the end of 2018, seven years ago. It contains a handful of blocks that create custom HTML that I use repeatedly throughout my pages. Before that I did it all by cutting and pasting the raw html everywhere I needed it. That was very tedious to maintain.

Gutenberg blocks are written in Javascript using a custom library based on React, the javascript library that Facebook developed to create Facebook.com. WordPress’s documentation for Gutenberg development wasn’t great back then, but it wouldn’t have mattered if it was. I didn’t know enough Javascript to understand it and I hadn’t even heard of React.

Like with React, you use a tool called “node” to run a script to install the files you need to create a WordPress plugin. That leaves you with a simple block that displays some text in a green box. I found examples online that helped me modify that basic green block to create my blocks and get them to do what I needed.

If you are familiar with WordPress then you know that you have essentially three areas that you care about when writing a page or post. In the editor you have the page content area and the sidebar where you can adjust attributes for the current block. Then there is the published page that your readers see. Most of what my plugin does is set attributes in the sidebar to generate the block’s content on the page.

Old block with the ugly green box

I didn’t know what to do with the green box in the page content area of the editor, so I left it there and had it display some of the attributes I set in the sidebar, including the image. What mattered to me was that the published page looked like it should, without any green box. I didn’t really care how bad it looked in the editor. Only I would ever see it.

The plugin has worked ever since so I felt no need to touch it again in the past 7 years. I was curious about React though, so put in some time to catch up on Javascript and learn React. I’m hardly an expert, but I know enough to look at some code and understand what it does.

That brings us up to now where the current version of WordPress changed things in their API and broke my blocks. To be clear, it’s all on me that my plugin broke. With an API, when the provider wants to change something, they mark the old method as deprecated and continue to support it for a few versions to give users time to update their code. The deprecation will trigger warning messages somewhere when you use those old methods. In the case of Javascript, those warnings go to the Javascript console in your web browser. I never thought to look. But when WordPress finally removed those deprecated methods in their most recent update, I certainly noticed.

Recreating My First Block

On my development system I have everything I need to run a local web server with WordPress. It’s all free software, which I love. Since I’m using Linux, all I had to pay for was the actual laptop hardware.

Since I understand JavaScript and React a little more now, if I’m going to work on my plugin I’m going to make it a lot better than the old one. For one thing, the green box in the editor is going away. The page will look more like I want the published page to look. That’s how it’s supposed to work in WordPress.

WordPress still uses node to install and setup the plugin and the starting block still creates the same green box. React has changed and matured a lot since it was first introduced, so the block API has too. The challenge in React now, and so with WordPress plugins as well, is that there is more than one way to do it. Javascript has functions, arrow functions, and classes that can all be used to do the same thing. But they work very differently. Since I’m not a pro at this, I want everything to be consistent so that I can more easily understand what’s going on and maintain it later.

npx @wordpress/create-block plugin-name --variant dynamic

WordPress’s create-block script generates skeleton code that uses straight old-fashioned functions, so that’s what I’m sticking with. When I did this last time I kept searching for examples until I found what I needed. Google doesn’t work that way anymore. Now we have Google AI. Instead of doing separate searches to get to what I need, now I can “dive deeper in AI mode” and refine my initial search without starting over each time. It has its advantages and disadvantages that I’ll go into later.

For my first block, I leaned on Google AI to learn what has changed in the WordPress API. One thing that I found was the option to make the block “static” or “dynamic.” I had no idea what this meant at the time, but the first example I found was for a dynamic block. Sounded good to me, so that’s the way I went. I learned what this means later.

New block without the ugly green box.

My first block is pretty simple. There is a list of attributes in the sidebar and it creates the HTML for the content I want to display. The only real changes are the names of the controls in the sidebar and creating the HTML I want in the editor’s content area instead of the default green box. Once I had the first block done I thought I had it all figured out. The rest were going to be easy.

The Next Few Blocks

The second block is a container block that can only hold instances of the third block. Think of a pie shelf that can only hold pies, and pies can only go on a pie shelf. I struggled a bit getting everything right so that the outer block (shelf) and inner block (pie) worked together correctly. Then I had to get the CSS right so that it looked like it should in the editor. WordPress has a lot of CSS of its own affecting how things look in the editor, so getting mine just right took some work.

The fourth and fifth blocks have a similar inner / outer relationship, so they were straight forward.

The sixth block is a stand-alone block like the first one, but it “displays” schema that bots, like Google, read to understand what’s on the page. It isn’t visible to visitors reading the page. Other parties define the schema format, so the work here was mostly in reformatting what I already had. I haven’t tested it yet because the Internet can’t see my development box to read the schema. Google used to have a schema test site. I hope it still does.

Creating a Custom Link

Creating a WordPress plugin to add links to a paragraph block and image block.

The next block was more challenging. My website displays affiliate products that I earn retail profit and commissions on. To earn my income, I need to be able to link the product on my page back to the company’s page so that people can buy the product. Managing those links by hand is a nightmare when the company does something with their website that breaks them all. So I store all of the links in my database so that I can update them all in one place. I don’t have to look for every link on my entire website. So one of the things that all the blocks do is create links, pulling the URL from the database. For block-type things that’s pretty easy. Creating a link on a bit of text that is embedded in a paragraph is something else entirely.

Originally I came up with this clunky block that stored all of the text before the link, the link itself, and all of the text after the link. I could only have one link in the paragraph and couldn’t do any other formatting on the paragraph text. But it got the job done.

The Right Way

This time I wanted to do it right. WordPress has it’s link button in the paragraph editing toolbar. Google AI found examples of how I can add my own button to the toolbar and format the link the way I want. This is completely different than writing blocks, because the paragraph is the block and WordPress owns it. But they are kind enough to expose some hooks so that I can inject my own formatting into it.

This is called a Format Type and uses a different part of the API to get and retrieve data. One thing I learned from this is that regular blocks store their attributes and everything in the HTML for the page in the database and it gets filtered out for the public-facing page. So visitors can’t see it by viewing the HTML source. But for a Format Type, the attributes are viewable by your visitors if they look at the source HTML. In my case, I’m creating a link by using a stored attribute to retrieve it from the database. If you look at the HTML of a regular link you see something like this:

<a class'link-class' href='https://www.address-to-somewhere-useful.com' title='Useful Place' target='_blank'>A useful place</a>

All of the attributes here mean something – “class” affects how the link is styled and “href” tells your browser where to go when you click the link. In my case I store a couple more attributes that don’t affect your experience of the link. But they have to be stored so that I can get the link from the database.

And this information is all stored and accessed differently in the API. The only thing that is the same as a block is creating the sidebar panel to edit the attributes.

It took a while to understand how this works, but now that I do, I’m very happy with it. The only thing left is to see if I can add my button to the image toolbar to create image links as well.

So Far…

I have written the previous blocks over the past couple weeks and the experience is beginning to fade. I’m working on the image link right now as I write this post.

The first plugins I wrote were completely my blocks. They have to work within WordPress but don’t try to do anything with content controlled by another block. The text link I just talked about is different because it formats text within a paragraph. Each paragraph is a separate block in WordPress, but they expose an API to access a piece of it’s content so that you can format it, like as a link.

Remember when I was talking about static vs dynamic when creating a new block? And I had that “–variant dynamic” flag on the create-block command? This is where I find out what that means. A static block creates everything in JavaScript and stores the final HTML so that when a visitor views the page it’s all ready to go. A dynamic block, like most of mine, stores only the attributes and doesn’t create the final HTML until a visitor accesses the page. In my case, I get the links for the the products on a page when someone visits that page. So if a link changes, all I have to do is update it in the database and all of the pages are automatically updated.

The key to this appears to be JavaScript vs PHP. The editor uses JavaScript for all of the block-related stuff, so the parts of a plugin that create the block content for the editor content area and sidebar are written in JavaScript. If you create and save the final HTML for the page in the JavaScript file then you have a static plugin. The visitor side of WordPress is PHP, so if you create your final HTML in a PHP file you have a dynamic plugin and it is never stored. It isn’t quite as simple as that because you do have to register your JavaScript and PHP files with WordPress so that it uses them at the right time, but it is close enough to keep things straight.

This means that the text link I created is a static link. It’s all in JavaScript. If I change the link in the database then I have to open and re-save the page in the editor for it to have the updated link. I have to see if there is a way to make it dynamic.

Creating a Link Around an Image

I thought wrapping my link around an image would be similar to the text link. In my mind I’m doing the same thing. But an image is a self-contained block without an API to get inside it. And if you understand HTML then you know that a link doesn’t really affect the image at all. It’s more like a container in that it surrounds the image. So it makes sense that I don’t get inside the image block like I did for the paragraph. So, again, what I want to do for this is completely different than what I’ve done before.

This time I am creating a Higher Order Component. As I understand it, I register a “filter” with WordPress to intercept the image before it is displayed. In the editor I intercept it to add my additional attributes and on the front-end I intercept it to actually wrap my link around it.

As I have said, I am relying heavily on Google AI to find examples of how to do this. This one was a much bigger challenge. I guess there aren’t as many examples for Google AI to find. I tried to put everything into my initial search to get back exactly what I want, but every time I refined my search I got back a completely different answer. This was very frustrating and not getting me anywhere.

So, the best thing to do is back up and try something simple. Don’t worry about getting stored links from the database. Just see if I can wrap an image in a hardcoded link. This is really no different than using the existing WordPress functionality, but I have to start somewhere.

Google gave me a simple example, implemented all in Javascript. So now, I have successfully intercepted the image to give it a URL and then wrap the image with a link so that I can click it to go to the URL. Good start.

The next step is to add my additional attributes to the editor sidebar so that I can enter them. This part is just like all of the plugins I have done so far. Easy. I create a fake URL for the link by adding my attributes together in a string. Then I can hover over the image and see my attributes in the browser’s status bar. That works. I see my fake link. Now to create the real link.

Make it Dynamic

This is where I actually learn the static vs. dynamic thing. Google AI tells me that I need to get the actual link in the editor and save it as an attribute. I don’t want to do that because that makes it static. I want it to be dynamic.

It took some effort to get a solution. Google AI seemed to think that I was insisting on Javascript. No, if PHP is the answer, which it is for a dynamic solution, then let’s do PHP. Just give me a complete answer so that I can put it all together. It did finally give me an answer. After I implemented it, I found that it was incomplete and had some errors. I was able to finally piece together a solution that worked.

There was still one little glitch. If I left align the image, then adding my link breaks the alignment. The alignment is applied to the image, not my link that wraps it. One more tweak to get the alignment attribute from the image and apply it to my link instead and I am good to go. It looks like it all works and it is dynamic.

There are still have some small tweaks to make. I want to go back to the text link and find a way to make it dynamic. Some single-line text boxes in the editor sidebar need to be multi-line so that I can see all of a text entry. The rest of the tweaks are mostly CSS-related to adjust white space between and around some of the elements. Nothing important enough that it needs to be done before I test the plugin and get it onto my real website. There will be time enough for small changes after my website looks like it should again.

Next Time…

AI is a huge buzz right now. As I said, I leaned heavily on Google AI for this project, so next time I want to share my thoughts on it and AI in general. See you then.

This entry was posted in Uncategorized. Bookmark the permalink.