Building a WordPress site plugin

Nearly every WordPress site can benefit from some custom programming. Code that tweaks things a little, usually using hooks (actions and filters) to adapt the output or how certain things function. These type of small changes are usually best organized in a “site plugin”, that is a custom plugin built for your specific website. This is done instead of the other more common “solution”, stuffing any custom code changes into the theme functions.php. Now there is a time and a place arguably, to use functions.php as a place to organize code. However theme stuffing as I tend to call it, is definitely over-used, and comes with many drawbacks.

At the very least you should ask yourself (as a developer) is the change I’m making really a presentation (theme layer) change? If not, use a site plugin. Even in cases where the change does affect the presentation, bear in mind if it involves any substantial logic it may not really be suited for the theme layer. You could make the argument for instance that a custom menu walker used to render the output of WordPress menu’s differently, is a presentation change. That’s true to some extent, however, that logic can be applied to almost anything that changes what you see in a web page, or template. The reason a custom menu walker would be better placed in a site plugin is because it may require future changes, and it’s a fairly substantial amount of code. A walker class can be several hundred lines. It is a PHP class, which should be your first clue that it belongs in a plugin.

As a site owner if you’re reading this and not sure when/where site plugins would help, that’s okay. My advice is aim to work with developers who have plugin build capabilities, rather than those who only work at the theme layer. You’ll get a lot more mileage from your developers in terms of extending and integrating plugins and API’s, and the benefit of keeping your custom code better organized.

Better organization of code isn’t just for a developers benefit. It has a direct impact on the cost and effectiveness of development. Site’s with a lot of theme stuffing can be very difficult to work on, time is lost sifting through poorly organized code. A well organized and commented site plugin can be structured to make finding custom code a lot faster, and that should translate into lower development costs.

A custom site plugin should not be the end all be all solution however, otherwise you may run into the same problems as in using functions.php. Although it’s fine to organize many smaller changes into a single plugin, it’s important to know when to create a second custom plugin (or 3rd or 4th) for specific site features. Don’t continue to expand the scope of your “catch all” site plugin which is there mainly as a utility plugin. If for instance you had an ecommerce site with a number of WooCommerce customizations, those should fit well into your site plugin. However if you have extensive subscriber management customization involving WooCommerce Subscribers, this is an area that probably deserves a second custom plugin to isolate that codebase.

Site naming conventions for site plugins should be kept simple and easy to understand. If the site name domain is “cancun-dental.com” use the domain name and make the site custom plugin name “cancun-dental”. Easy peasy. Now if you have need for more custom site plugins consider adding to that name such as for the example WooCommerce Subscriptions customizations, the plugin name would be “cancun-dental-subscriptions”.

Using the Meta Box plugin as a foundation for your plugin

In the past I used to use ACF as the field system for many of my plugins. I’ve been a programmer since before there were field systems, and before there were CMS systems. I’m just really, really old now lol. Point is, I don’t see the point of spending the time creating forms and fields. That stuff has been done, and done again, and odds are when you reinvent the wheel that way you’ll make mistakes. Either ACF or Meta Box take care of infinite numbers of things you would never get around to when building your own field handling system.

I’ve recently switched from ACF to Meta Box. And I’m hugely excited about it, because as I pointed out in a recent post Meta Box is awesome! In this post I’m going to share with you the overall idea of how to use Meta Box in your plugin development. It’s an overview, so I’m not going to give you a lot of details, I’ll be posting code samples and more details on this approach later. If you’re a seasoned WP Plugin developer odds are you can read the Meta Box docs and piece things together yourself… what I want to share is the strategy, the methodology behind using Meta Box within a plugin.

Here is a common scenario in many plugins, written as requirements:

  • Custom Post Type (CPT) such as “animals”
  • Animals have distinct data fields such as “Number of Legs”. Your goal is partly to make managing the animals easier, and partly to better support displaying the animals.
  • Provide a custom single template for each animal post
  • Provide an archive page that is custom and in some form lists all the animals, possibly just a directory style list, but possibly a more advanced approach with search and filters.
  • Other possible requirements:
    • Support searching by meta such as finding all animals with 7 legs. By the way there are many animals with 7 legs, they’re called the spiders that escaped my foot.
    • Provide front-end submission of animal posts
    • Display animal posts in a widget or shortcode
    • Organize animal posts with a custom taxonomy
    • Connect animals to another CPT as either parent or child, for example an animal rescue agency might want to have “orphans” (pets available for adoption) which is referenced from the animals post

First off let’s look at where Meta Box would come into play in the above. It won’t do every one of these things, but it will support you in building out all the requirements listed above.

  1. Registering the CPT. You can register your CPT with the Meta Box Post Types extension. During development can register it using the interface, then export it to PHP and bundle that export into your plugin. If the plugin is for a single website though, you might continue using the interface driven post type instead. Personally I would always export simply because I want any plugin I build to be portable. The Meta Box Post Types extension to me is a utility tool, a valuable one that saves me time. But I won’t rely on it for the finished product.
  2. Meta Box Post Types extension can provide any taxonomies used.
  3. Meta Box provides the fields for the CPT, organized into metaboxes. Meta Box extensions can be used to improve the interface such as adding tabs, or repeating groups of fields. For me those two features are must-haves in most plugins I build.
  4. Meta Box can provide the front-end form for submission with an extension.
  5. Meta Box can create the references between the CPT and another CPT using post type fields, and with extensions there are different field and selection options.
  6. Meta Box provides functions to get field values which you’ll use in your custom templates.

Meta Box basically does most of the heavy lifting here to create the features I listed in the requirements above. Where you’ll need to fill in the gaps are mainly the template handling. I like to use a template override system which I first created for the WordPress quiz plugin QuizMaster. It’s been refined across many projects, and in it’s current version is integrated into Clay Framework. What it does is search the site active theme and find a template override, and if none are found it loads the default template within your plugin. You’ll need to build these default templates, using Meta Box get value functions to retrieve values and determine logic such as switching display based on values.

Imagine being able to cut as much as 80% of the work down on your next plugin build. That’s the power of Meta Box integration for WordPress plugin development. Have fun building, and stay tuned for follow-up posts where I’ll go more in-depth into implementing Meta Box features in a real plugin build.

Metabox plugin is awesome

How awesome is the plugin metabox from metabox.io? It’s amazing that’s what! Look, I’ve been an ACF fan for years. Coming from a Drupal background the first question I had about switching to WP development was “does it have a field API”? The answer was no, but try ACF. And I did. And I came to rely on it for just about everything. Long story though, I eventually became less enthused about ACF. I very much regretted embedding ACF into QuizMaster for instance, which is a different topic.

Metabox in my view stands head and shoulders above ACF. I actually like their extension driven approach, which I think is a good structure for WordPress plugins in general. ACF interestingly enough was extension driven earlier on and has since gone away from that model. Of course 3rd party developers can (and do) still publish extensions for ACF, but there is something about the core using the extension system that I trust a lot more. Meaning it’s one thing to say you can extend a plugin (but we don’t!) versus saying you can extend it using the same extension system we just used to built all these extensions over here. Metabox can say that, ACF cannot.

I’m not familiar enough with the Metabox extensions yet to say if Metabox can do all that ACF could. A quick tour of their extensions directory (salivating at the prospect of buying the development license!) and I found several extensions that do stuff I always wanted to see done in ACF. It looks to me like they either kept tabs on what ACF customers were asking for (and delivered it) or they just have a great vision of what a field system should be capable of. For instance one of the pet peeves with ACF is the way it stores data. It essentially “doubles” for lack of a better word, the meta storage for each field value. One meta entry to reference the key, another to reference the value. Something like that (it’s complicated). Now with ACF or Metabox you might not ordinarily be accessing the meta directly anyway… but if there is one thing I know about strange ways of handling things in any system, you usually suffer for it eventually. ACF’s odd way of storing data was often cited as the reason the developers could not deliver certain commonly requested features. Exporting values for instance has always been weakly supported by ACF.

Is this a post about ACF or Metabox you might ask? Well getting back on track here… Metabox has an extension that allows you to store your field values (meta data) in a custom table. There is one example of how it offers flexibility that ACF (AFAIK) does not. Another is something like a “merge data” option that enables grouping data together to reduce the table rows. Meta data does have the risk in WordPress of quickly piling up a massive number of table rows, WooCommerce for instance stores something in the range of 40 rows per order! Just think how that can add up on a high volume website.

Here are a few of the things I’m liking best about Metabox:

  1. Online Meta Box field and metabox generator. Visit https://metabox.io/online-generator/ to try it out yourself.
  2. Extension selection of Meta Box Extensions available at https://metabox.io/plugins/. Many of the plugins are free, and for the premium plugins the licensing terms and prices are fair, especially if you buy either the developers license or the lifetime license.
  3. Data storage as regular post meta. Unlike ACF the Meta Box plugin stores post meta in much the same way we would normally, so it’s easy to retrieve manually even without using the Meta Box value getters. There is also an extension that can store your data in a custom DB table.
  4. Easy to integrate into a theme or plugin. Current versions of Meta Box integrate even more easily than in the past where it took setting constants and possibly using a class. Today it takes 1 line, that’s it! Perhaps to avoid conflicts or check for versions it is worth wrapping that integration in some form of plugin activation check, but if you own the site you’re building on you can just be sure to integrate Meta Box only once. 
  5. Great support by dedicated developers. After using Meta Box only a short while I’ve already been in touch with the developers and they provide great support. It’s clear from their regular updates and involvement with their community that their very dedicated to the Meta Box project.

Well I’m off to integrate more Meta Box extensions into Clay Framework which powers GoldHat.ca. Stay tuned for more articles about Meta Box including some tutorials as I continue learning and working with it.

Setting templates from your plugin

Often when we make CPT’s (Custom Post Types) we want to provide a default template to render the single posts. We also want that template to be overridable in the theme layer. The answer is the filter single_template which allows us to direct WordPress to load the template from our plugin. As for making it possible to override the template, we won’t cover that here but you can learn about how we do this in QuizMaster and Clay Framework by watching this video: https://www.youtube.com/watch?v=aQyQ615oWcM.

Example code below shows the use of single_template filter to select a template from a plugin.