I recently posted about how to include a plugin in a WordPress theme properly. Here I will touch on the converse – how to make sure your plugin will work nicely if it is loaded by a theme.
My general approach to development is to create discreet features that can interact with each other in elegant ways. By keeping each set of features small, they are simpler by design and implementation – this makes both them less prone to bugs and easier to reuse. You can see this approach in action in many of Crowd Favorite’s WordPress products. For example we created our Admin Post Formats UI as a library that can be easily reused rather than coding that feature into our FavePersonal theme directly.1 Another example, Carrington Build includes a plugin to enables translation of it’s data when being pushed from staging to production by RAMP.
If you start with the mindset of “I’m creating code to implement a feature, and this code should be as re-usable as possible”, then you’re already in good shape.
Here are some specific things to consider:
- Don’t use activation or deactivation hooks. There are actually lots of reasons why these are a bad idea, including multi-site considerations, upgrade considerations, etc. Instead, pick an opportune time to do a lightweight check to see if your plugin set-up needs to be run (perhaps check the existence of one of your settings – perhaps an “installed version” setting) and do the work you need to do at that time. Remember, you want to do these checks in admin hooks rather than front-end hooks – you don’t want to add unnecessary overhead to every public page load and you want to avoid race conditions.2
- Don’t reply on your code running prior to all code being loaded. Hook in at
wp_loaded(previously this was done at
init) to do any set-up work, etc. The only situation where this might not be possible is if you need to override a pluggable function, but the types of plugins that need to do this are (in my experience) less likely to be the type of plugin included in a theme.
- Don’t rely on settings existing in the database. This ties in with the first consideration as I often see default settings written to the database as part of the activation process. I take the approach of creating an accessor function in my plugin that holds a set of defaults for settings. Here’s some example code:
It’s also worth noting that all WordPress.com VIP sites load plugins by including them within the theme code. If you’re writing code that might end up on this infrastructure, you’ll be glad that you followed the steps above.