Here’s a confession/admission/realisation (all of the above, tbh) – a couple of years ago my coding standards slipped. In a desire to simply “get stuff done” I lost focus of some of the fundamentals that every good coder should really adhere to; regular readers, however, might recognise that I’ve been exploring that realisation over the last year or so as I strive to not only find my mojo again but also pick up on some new skills tha will help me going forwards. One of the things I’ve known I need to pick back up on is proper Object Oriented coding, something that I feel it’s easy to get out of a habit of doing when you’re working in WordPress. My explorations of Symfony led me to touch back on that again, but a conversation with someone last week started me looking at how I could introduce it into my WordPress work.
A days worth of research later and I was set to start building class based designs into my plugins. At first I started looking at one of my old plugins, the Custom Field Editor. That plugin basically enables a shortcode based system for building forms on the front end that can then be used to add entries to the post meta for recalling. It was a part of the EPortfolios project that I’ve mentioned a number of times on here and is really designed to be hidden behind a login. Long story short, trying to turn this into a class model led to a LOT of frustrations, mainly in how PHP classes behave (they technically have to be in one file, not split over multiple files as I normally do) and how they behaved in respect to the idea that the plugin embeds multiple shortcodes within one main one (for some reason the embedded shortcodes broke the rendering of the main one).
So I took a step back and decided to code a very simple class based plugin starter that I could use in future projects. The result is something I’m hugely pleased with, mainly because it made me realise how easy it is to build WordPress plugins in a class, but also because it allowed me to tick another to-do off my list; split out markup from my PHP functions, in this case with the implementation of a rudimentary templating engine. You can find the starter class here, so feel free to grab and use it.
What is this doing, then?
There’s a few key things at play here so I’ll do my best to split them down:
- base.php is a “core” class file which defines some standard functions and vars that would be usable across any plugin, things like setting the root folder, magic functions and the template renderer (we’ll get onto that in a bit)
- wp-plugin-starter.php, meanwhile, is the main plugin class. This extends the base class and sets its own vars and logic. In the case of the starter it generates a basic admin screen and shortcode.
- The constructor does most of the heavy lifting with the WordPress API, grabbing settings for the admin and setting up functions that tie into WordPress specific hooks. Because we’re in scope of the class, we need to reference the callback functions as an array – array($this, ‘function_name’)
- The shortcode function itself is probably more complex than it needs to be. As I mentioned, I like to split my code down into manageable chunks, but PHP class definitions are required to be in a single file. To get around this, I put the code that sits within the function into another file and included that, keeping the variables in scope. The only gotcha here was that I couldn’t “return” from this file, something essential for WordPress shortcodes.
- Finally, after the class has been defined, the plugin file instantiates the class. This triggers all the API hooks, grabs the data from WordPress and basically makes the plugin “work”. As WordPress reinstantiates this every page load, the constructor will always be getting up to date data from any admin settings, so everything operates smoothy and as expected.
This provides a good foundation that can be expanded on to build plugins and will be the way I tackle this going forward.
The template engine
I think template engine is the right term here. It’s not something like Twig, but it was based on a very timely article from Chris Geelhood on CSS-Tricks that explored how to write a simple render_template function for PHP that takes a template name, a bundle of data and pushes something to the screen. I made a couple of modifications to this in context of the class:
- The path is made up of the plugin path and view path. At present this view path is hard coded into the base function and is relative to the plugin root (‘/views’). These values are stored in the object so that they can be easily accessed by all its methods.
- I added a bool flag so that a function can decide whether to render direct to the screen or return the output buffer to the calling function. This was, again, due to the nature of shortcodes needing to return their content to be rendered at the correct place on the page but I can see it potentially having other uses.
I’ve split this function out into a separate repository so that it can easily be included in other PHP projects and you can find it here.
It’s easy to let your standards slip or at least get into habits that are entirely of your own making when you’re not part of a fully technical team, but I’m pleased that not only have I proven to myself that I can pull past knowledge to the fore, I can also add to it in a meaningful way that will make future projects a lot more manageable.
My next goal is to properly refactor the Custom Field Editor plugin – I’ve got a great idea as to how I can rework it so that it has a low reliance on shortcodes which I’m eager to put into place.
I’m also conscious that the idea of the shortcode is becoming somewhat redundant in the move to Gutenberg, so another future goal will be to look at migrating my knowledge to blocks!
As always, you know where the comments are – shout up if any of this has been useful for you!