Software Engineering in WordPress and Musings on the Deep Life

What Are Object-Oriented WordPress Meta Boxes?

I’ve written several posts about WordPress meta boxes. Perhaps the series of posts closest to what I’m going to touch on in this post is the one that outlines:

  1. Aiming For Simplicity
  2. Separating The Logic
  3. Each Component
  4. The Front-end

You can read each of these if you want, but they aren’t necessary for this particular post. If you’re familiar with WordPress meta boxes and how to create them programmatically, then you should be good to go.

The short of it is this:

There’s a consistent way to create WordPress meta boxes in an object-oriented way. This includes an interface, defined methods, and permission and security checks.

A lot of people who work with WordPress use third-party code to create these features. This includes other plugins or generators. That’s fine. I’d say that falls more into the implementor camp, but that’s beside the point.

Further, it’s not the point of this post. Instead, this post focuses on concepts for WordPress developers looking for object-oriented solutions.

WordPress Meta Boxes

If you work with WordPress long enough, you’re likely going to need to create a meta box. Honestly, you’re probably going to be creating a lot – especially if you do a lot of client work.

The nice thing about meta boxes is they are predictable. That is, at least as it relates to how to create them. To that end, it’s easy to put together some scaffolding for your meta boxes.

Of course, the implementation will vary. But that’s programming, right?

Anyway, given that there’s a predictable way to create meta boxes, I thought it would be worth sharing some code that outlines an object-oriented approach to WordPress meta boxes.

This post assumes you’re familiar with what they are and how they work, as well as the rest of the information in the Codex. If you’re not familiar, then I’d recommend reading that article first.

1. The Interface

Interfaces are part of the core of object-oriented programming. They provide a contract that any class that implements it must follow.

Since meta boxes have a predictable setup, it’s an ideal place to create an interface. A general interface for a WordPress meta box may look something like this:

Obviously, this does not include any specific business logic. And it shouldn’t. Instead, it only provides the functions that should be common to all meta boxes.

Business logic – or domain-specific logic – should live at the class level.

2. The Classes

Creating a class for a meta box is pretty easy. Assuming you’ve implemented the interface, you need to do the following:

  1. Register a hook for creating the meta box.
  2. Create a function for displaying the contents of the meta box.
  3. Register a hook for saving whatever the user has provided.

At the highest level, this would look something like this:

But this raises two questions:

  1. What about permissions and security?
  2. Why is the display logic a separate file?

First, permissions and security can be generalized only so far. That is, we can check for permissions and nonce values but the specific implementation of your class may be more (or less) stringent.

Secondly, the display logic is in a separate file because I think that keeping anything that’s template related – even if it’s just a partial template – should live in a separate file.

Though you can include markup and and styles in a single PHP file, it muddles the code. You’re mixing languages at the highest level which isn’t necessary.

This hurts maintenance, readability, and extendability.

3. Starting The Plugin

To round out the above code, here’s how you may end up stubbing out the plugin’s bootstrap:

Of course, this is just an example and the actual implementation is largely contingent on what you plan on creating. This just sets everything created up above in motion.

4. File Organization

Once you have the basic functionality of your meta box completed, you’ll probably want to add stylesheets, JavaScript, perhaps images, and other assets.

Before doing that, though, it’s helpful to have a plan for how you’re going to organize your files. Here’s how I do it:

Meta Box File Organization

This isn’t necessarily the best way to do it, though. It’s a way that I use, it’s a way that’s worked well, and it’s something that’s become tried and true the longer I’ve worked with WordPress.

4. Other Functions

If you’re introducing assets, then you’re going to need other functions. This includes things like registering hooks to include your stylesheets and your JavaScript files.

In this case, you’re going to need to introduce more add_action calls into the initialize function. This will result in you adding more public functions to your class.

That’s okay, though. It’s not violating the contract as defined by the interface. And it’s providing functionality specific to your implementation. That’s standard object-oriented programming.

Furthermore, you may need to introduce more protected or private functions. Or maybe you’ll need to introduce other classes. Whatever the case, that’s normal.

Remember, the point of the interface and the basic set of function definitions is to provide the core functionality of the meta box. Everything else is specific to your problem’s domain.

It’s Not Definitive

This isn’t the definitive way to create a WordPress  meta box, but it’s what I’ve found helpful.

Whenever I work on a project that calls for this type of functionality, this is basically the approach that I end up using. Sure, I might tweak it a little for my implementation, but the gist of the meta box remains the same:

  1. Initialize it
  2. Setup a `display` function
  3. Define a `save` function

The rest are details all relevant to what you’re doing.

20 Comments

  1. Rafal Gicgier

    With Advanced Custom Fields for WordPress Meta Boxes API has lost its meaning long time ago.

    Regards,

    Rafal ;)

    • Tom

      With Advanced Custom Fields for WordPress Meta Boxes API has lost its meaning long time ago

      This isn’t completely true. I genuinely does depend on the project.

      There are other plugins, like CMB2 that also offer functionality like this.

      Secondly, including a third-party plugin into a custom solution for a client can be heavy-handed and it introduces yet-another-dependency that isn’t necessarily needed depending on the requirements of the solution.

      It’s bringing that proverbial hammer to place a thumbtack in place.

      I’m not knocking ACF or CMB2. I’m saying that it’s important to know when to use them and when not to use them. And if you’re using them for everything then you’re either focused on a single type of project or you’re going overkill with some projects.

  2. Rafal Gicgier

    Well the main reason for using ACF is that it’s actually getting updated pretty often and will most probably continue being updated. With a custom Class one’s project might end up outdated at some point. The second thing is that the project is not that heavy and won’t impact the site’s performance.

    Apart from a really simple site where there would be just several Meta Boxes I see no real advantage of using the class; obviously you may want to do this in case you were to sell your self-made theme but you don’t have to ACF (or any other similar) would apply here.

    Can you name a few projects where you’d rather rely on a self made Class please?

    I have a feeling that someone will pop in, and say that there’s no reason for using WordPress if one could use a smaller PHP framework – “this depends on the project” – he’d say ;)

    • Tom

      Well the main reason for using ACF is that it’s actually getting updated pretty often and will most probably continue being updated.

      Oh for sure – it’s well maintained. Though once of it’s previous versions did break compatibility with some sites. That’s the nature of software, of course, but I know that it irked some one.

      For more general solutions, sure, using ACF is fine, though. I don’t disagree with that.

      With a custom Class one’s project might end up outdated at some point.

      If I’m responsible for building and maintaining someone’s web application or web site, there’s not a chance that it will become outdated because I’m the one maintaining it and they are my client.

      I don’t throw things over the fence for other people and say “Good luck, nice knowing you” :). They are ongoing clients with which I have a relationship.

      This isn’t to say your point is wrong because there are certainly times in which this happens. But this doesn’t happen in my case, and there are developers and agencies who work in the same fashion as I do so this idea of ‘Class rot’ is something that’s relative to the case in which it’s being applied.

      For me, it’s not relevant.

      Can you name a few projects where you’d rather rely on a self made Class please?

      Many of these are client projects. These include:

      • Web applications dealing with product reviews
      • Sites dealing with hardware mouldings for homes and commercial properties
      • A site that ties into a custom database table
      • A property dealing with teaching others that integrates with a third-party plugin API
      • An intranet-based site that uses a portion of several third-party plugins to help drive its API

      I can go on, but I figure five is good enough for now, right?

      The point I’m trying to make is that ACF nor CMB2 are useless. They aren’t. They are very useful, very powerful, very respectable packages. But they aren’t the end-all-be-all of meta boxes and custom fields in WordPress development.

      I have a feeling that someone will pop in, and say that there’s no reason for using WordPress if one could use a smaller PHP framework – “this depends on the project” – he’d say ;)

      Oh sure. But if the client comes and says they have an existing WordPress installation and they want to extend the functionality such that it includes X, Y, and Z, then it doesn’t make sense to use another PHP framework.

      I’m not trying to be that guy and say “It depends.* That’s facetious and I don’t want to be that way. Everything here is meant to be taken in context of WordPress and a given solution.

      And sometimes, that does depend. That’s not a copout answer.

  3. pieroit

    I appreciate the work you are doing to promote OOP oriented concepts into WordPress.

    • Tom

      Thanks! I’ve more to come, as well.

  4. Rafal Gicgier

    Hmm I can’t seem to be able to reply directly to you. An edit and a short info on how to use the HTML elements here would be handy either ;)

    “Oh for sure – it’s well maintained. Though once of it’s previous versions did break compatibility with some sites. That’s the nature of software, of course, but I know that it irked some one.”

    Well the point is valid. However this depends on the frequency and size of the projects. I usually work on a small to middle sized projects, doing around 5-10 a month. Using a custom framework, even if it’s constantly updated might require monthly updates to each of these clients and having to go through up to 120 sites a year might be a real PITA.

    “For me, it’s not relevant.

    Can you name a few projects where you’d rather rely on a self made Class please?

    Many of these are client projects. These include:

    Web applications dealing with product reviewsSites dealing with hardware mouldings for homes and commercial propertiesA site that ties into a custom database tableA property dealing with teaching others that integrates with a third-party plugin APIAn intranet-based site that uses a portion of several third-party plugins to help drive its API

    I can go on, but I figure five is good enough for now, right?”

    I was rather referring to the direct comparison where NOT using ACF is a real, true and enormous benefit of doing so. The examples don’t seem to discourage ACF. Needless to say, a custom and differently structured database table might do the trick here.

    “Oh sure. But if the client comes and says they have an existing WordPress installation and they want to extend the functionality such that it includes X, Y, and Z, then it doesn’t make sense to use another PHP framework.”

    Yeah – most probably this could be my argument against yours. Probably with the number of ACF supported plugins you’d achieve the expected much faster.

    “I’m not trying to be that guy and say “It depends.* That’s facetious and I don’t want to be that way. Everything here is meant to be taken in context of WordPress and a given solution.”

    You’re most right, neither do I. I may be influenced by the type of work I do, however I have most of the time managed to come up with a solution even in case of bigger projects (say the ones lasting for several months).

    What I also see is that the clients seem to be more understanding and they prefer ACF over hand-crafter solution.

    Summing things up I approve the type of posts you post, especially focusing around OOP, however I think that recreating a wheel reduces one’s productivity.

    This whole “problem” might actually be a good idea for your next article, say when to rely on plugins, when to rely on custom work.

    I have to admit that I’m not the install a plugin-to-do-the-job type it’s just that there are several essential plugins which will hasten ones work.

  5. Jimmy Romanowski

    This article comes at a great time. I’m currently building a job board plugin for my company. I’ve included CMB2 in the plugin but feel as though I should switch to using the class as laid out in this article. This plugin will not be released to the public just for internal use.

    Do you think using the class is a better option in this case or does it matter?

    • Tom

      Do you think using the class is a better option in this case or does it matter?

      Without knowing the specifics of what you’re doing, it’s hard to say. If the CMB2 fits the bill, is easy to work with, meets your needs, and isn’t heavy-handed, then you’re probably good to go :).

  6. Ryan Hellyer

    I appreciate the logic behind why you do things this way, but for simple meta box implementations, I prefer to keep everything constrained within a single class. This makes it very clear what relates to the meta box, and what doesn’t. If someone comes along to read the code later, they don’t need to bounce through multiple files, or refer back to an interface to figure out what is going on.

    Here is a simple copy and paste class that I tend to use for these sorts of purposes … https://geek.hellyer.kiwi/tools/meta-box/

  7. Jake Jackson

    Good work using an interface! Carl Alexander would be proud of your effort to further OOP in WordPress.

    • Tom

      Thanks :). I’m a fan of using interfaces before actually going out to build my classes (it also helps to create Mocks when doing testing, but that’s a topic for a whole other post!)

  8. Carl Alexander

    This was a cool take on OOP and meta boxes! I would have tried to push it further a bit with the metabox interface. It’s not used by any other class or function which is a bit sad (Poor thing needs friends!).

    I haven’t experimented too much around the metabox API myself. A cool idea would be a custom mbe_add_meta_box function that uses the interface. It’d populate the call to add_meta_box using methods from the interface. That would replace the need for every metabox to call it.

    • Tom

      It’s not used by any other class or function which is a bit sad (Poor thing needs friends!).

      In this post it’s not, but if I was creating mocks and doing unit testing that wouldn’t be the case! :)

      It’d populate the call to add_meta_box using methods from the interface.

      Ah, now that’s an interesting take. Haven’t thought about doing that before.

  9. Ataul Ghani

    Nice post…. Lot’s of point come-out. I really appreciate it. :)

    • Tom

      You got it, Ataul – glad to help!

  10. Atinder Gill

    Hi Tom,

    Looking like very helpful post, because i was searching on internet regarding it and found this post here. i’m using WordPress platform from last year and still learning so helpful post.

    Thanks :)

    • Tom

      Glad to hear it, Atinder!

  11. Ihor Vorotnov

    I’ve recenty used your old tutorial on media uploader in a metabox to implement it for taxonomy terms instead of posts. As you know, add_meta_box() works only for posts/pages/cpts, so I rewrote it to work for terms. There’s also user add/edit page (Pippin has good tut on that). I think 2 more classes for that cases can use your interface as well. Add one for options/settings page, and you’re 100% covered.

    /methinks I might have a look into this next weekend…

    • Tom

      That sounds great – nice work!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2023 Tom McFarlin

Theme by Anders NorenUp ↑