“Requiring” Plugins

I’ve started working on a redesign of this site (spoiler alert: it’ll be responsive! Eventually.), and one thing that’s kind of dogged theme developers (I think) is what to do about plugins that are pretty much required in order to make your theme go.

To this point, it hasn’t been an issue for me. Pretty much every theme I’ve developed has been unique for a particular client, and I have as yet attempt to release a theme to the WordPress theme repository. Ergo, if I required a plugin for the project, I installed it. Boom, done. However, in creating a theme for the general masses, I could totally see me needing to include something like a plugin that lets you add classes to widgets and that sort of thing.

So the question becomes, how best to go about this? I see three possible solutions:

“Include” the Plugin

For the redesign of this site, I’ve taken the plugin Custom Widget Classes, put it inside a “plugins” directory in my theme’s directory, and did the whole PHP require thing in my functions.php file. Of course, I give attribution in the source code. Besides, the whole plugin is there, meta data, licensing and all.

However, this approach has a couple of drawbacks: First, if the plugin is poorly written (and I’m not saying this is necessarily true of Custom Widget Classes; I’m just saying, generally speaking), it might not take too kindly to being moved out of /wp-contents/plugins/. I was working on a site for the client the other day where I had to rename a plugin, including the name of its directory, and because it had that directory name hard coded in lots of places, it was a pain to have to go in and fix. Another drawback is you’ll have to go into the plugin code and make sure that all of the functions it declares are wrapped in if ( ! function_exists() ) { } structures, to protect against the person installing the theme already having the same plugin installed. Again, this is something that the plugin developer should do, but, well, you know.

So while I like this approach, it might not be the best way to go. Heck, while it might be technically allowed to redistribute a plugin in this way, is it something that’s frowned upon or not? I just don’t know.

Inform the Downloader of the Required Plugins

This means shifting the responsibility of installing plugins to the user, which I don’t like because, as someone once said, “Don’t make me think.” On the other hand, it gives them the control whether to ignore you or not, so long as they understand the risks of not installing the “mandatory” plugins. Of course, they won’t read your instructions and/or warnings, so they won’t understand said risks, and start complaining left and right on the support forums how your theme is a piece of shit. This is probably my least favorite option.

Bake In the Desired Functionality Yourself

This is very, very much like the first option, except it’s more like reinventing the wheel. One of the reasons that WordPress thrives as it does is its rich ecosystem of third-party themes and plugins that do pretty much anything you can think of. Why repeat this hard work that’s already been done? Besides, in reality, it’s going to be a lot like the first option in that you will likely have to copy and paste someone else’s code into your work. From what I understand about the GPLv2, I think this is allowed? (I’m not totally sure, I prefer the WTFPL myself.) In any case, you do have the advantage that by namespacing the functionality, you’re less likely to run into conflicts with having the “same” plugins already active. But for the theme developer, it seems like a whole lot of extra work.

Bonus Option: Don’t Require Anything

I’m not sure that this is a realistic answer. After all, there are a lot of plugins out there meant to enhance the presentation experience (the aforementioned widget class plugins, for example). If your theme wants to leverage this kind of additional control, it needs to be included in some manner. Not including it and settling for a theme that is less capable seems like short-changing the potential users.

Conclusion

Someone, somewhere, way smarter than me has probably already figured out the best solution to this. If so, I’d love to know what that is. Or am I right in this being an unresolved issue in the community? Please let me know your thoughts in the comments. Thanks!