There is no right way.
However, there are still ways to do it if you absolutely need to.
Let’s admit it. As developers, we’re lazy. We don’t like installing multiple tools when they could be bundled into one package. We don’t like teaching our clients the difference between functionality and presentation. We don’t like documenting the multiple items we installed on a client site so the next guy can not break things when he works on it.
We’re lazy. As a result, we try to take shortcuts whenever possible – one of those shortcuts is bundling plugins with themes to extend WordPress’ functionality. But if you must take such a shortcut, here are the “right” ways to invoke
TGM Plugin Activation
A couple of fantastic WordPress developers have taken the time to pull together a utility class for placing plugin dependencies in themes: TGM Plugin Activation.
Add this class to your theme and register its plugin dependencies. Then, when users activate your theme, you can automatically download, install, and activate any missing required plugins. This has a huge benefit – the plugins are regular WordPress plugins and are installed using regular WordPress functionality. In other words, when updates are released, WordPress handles the updates exactly the same way as any other update.
The downside, though, is the somewhat large footprint of the class. The single PHP file is a whopping 2,000 lines of code – so for automatically including smaller plugins it can be a bit overkill.
Copy the Implementation of
This is the pattern modeled by Alex King in his tutorial – it involves bundling the plugin directly with the theme and loading the core plugin file the same way WordPress does. The advantage here is that you’re not doing anything exotic – you use the same functionality WordPress does to load the plugin. In addition, using Alex’s model, your bundled version of the plugin is automatically overridden by a standalone installation of the plugin.
The downside, though, is that you’re including the plugin in a location WordPress doesn’t expect. It won’t detect updates to the plugin, so if things change you need to re-release the theme.
The right way to include plugin functionality in a theme is to not include plugin functionality in a theme.
Instead, build your theme under the assumption that the plugin is installed and active. Then, hide any dependent functionality behind hooks – actions and filters. You want to add specific social sharing widgets below a post? Great! But don’t call
custom_sharing_widgets() directly. Instead, add a hook to your theme and wire the hook up in your theme’s functions file:
// In functions.php
if ( function_exists( 'custom_sharing_widgets' ) )
add_action( 'my_theme_below_post', 'custom_sharing_widgets' );
// In single.php
do_action( 'my_theme_below_post' );
If the plugin is installed, the widgets are automatically placed in the right area of the theme. If not, nothing happens. Using actions like this, you can support multiple similar plugins – just tie in the same hooks. Then your users can decide on their own which plugin to use to add this functionality.
Actions and filters are insanely powerful, and you can define as many as you need. Just look at premium themes like the Genesis framework and all the awesome hooks they provide. It’s relatively simple to customize the layout and hooking in new functionality.
Just remember, plugins and themes are meant to server vastly different purposes. Mix and match at your own risk.