Packaging thirdparty plugins with your WordPress theme using TGM Plugin Activation library

When you’re shipping your theme for sell, it’s often required to bundle the required plugins. Some people just keep these plugins like general vendor libraries inside their theme and load them using php’s require_once. However, if you’re following this style, your themes will fail to pass the theme check because these plugin files will be considered as a part of your theme, and it will prompt you that CPT functions and shortcodes should be a part of the plugin. Moreover, if someone deactivate your theme, those shortcodes and CPTs will be unavailable immediately.

This is why, along with many other developers, we use TGM Plugin Activation library. This tiny little lib can force or suggest installing the plugins which are required (or good to have) for making your WordPress theme work flawlessly.

TGM can work with plugins which are hosted in WordPress plugin repository, or in a github public repository. It can also work with plugins which are shipped with the theme as a separate zip file. In this article we’ll see all these three cases of plugin installation and activation process using TGM library.

Bootstrapping

Download the TGM library from http://tgmpluginactivation.com/download/. After unzipping, keep the class-tgm-plugin-activation.php file inside vendors/tgm/ inside your theme. Then add the following code in your functions.php

[code lang=php]
require_once get_template_directory()."/vendors/tgm/class-tgm-plugin-activation.php";

add_action( 'tgmpa_register', 'theme_slug_register_required_plugins' );

function theme_slug_register_required_plugins() {

$plugins = array();

$config = array(
'id' => 'tgmpa',
'default_path' => get_template_directory()."/plugins/" ,
'menu' => 'tgmpa-install-plugins',
'parent_slug' => 'themes.php',
'capability' => 'edit_theme_options',
'has_notices' => true,
'dismissable' => true,
'dismiss_msg' => '',
'is_automatic' => false,
'message' => '',
);

tgmpa( $plugins, $config );
}
[/code]

In the above codeblock, default_path is a very important one. It helps TGM to decide from where it should look for the bundled plugins. Make sure you’re giving an absolute file path. Right now, it’s pointing to the plugins directory inside our theme.

If the value of is_automatic is set to true, all the necessary plugins will be installed as soon as the theme is activated, without nagging the user.

Now, let’s add some plugins to the $plugins array. This is the place where we will be listing all those plugins required for our theme.

Plugin from the theme’s directory

When you have to ship proprietary plugins as part of your theme, this is how you’re going to do it. In this example below, we will prompt our user to install the Visual Composer plugin. We’ve kept the js_composer.zip file inside the plugins folder in our theme.

[code lang=php]
$plugins = array(

// This is an example of how to include a plugin bundled with a theme.
array(
'name' => 'Visual Composer', // The plugin name.
'slug' => 'js_composer', // The plugin slug (typically the folder name).
'source' => 'js_composer.zip', // The plugin source.
'required' => true, // If false, the plugin is only 'recommended' instead of required.
'force_activation' => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch.
'force_deactivation' => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins.
),
);
[/code]

It will look like this in your WordPress themes screen

It’s important that you properly write the slug. It’s simple, just unzip the plugin zip file and take the folder name as it’s slug. If your theme has a hard dependency on this plugin, you should set the required to true. Otherwise, it would just like an optional plugin which is not required, but good to have. You can also set the value of force_activation to true in case you want this plugin to be automatically activate once installed. If your theme breaks without this plugin, then you would never want your users to deactivate this plugin as long as your theme is set as the active theme. In such cases, you can set it’s value to true

Plugin from the WordPress plugin repository

Well, in our previous example you’ve seen how to prompt your users to install a plugin that is bundled in a zip file in your theme. Let’s have a look to how we can prompt them to install a plugin from the WordPress plugin repository. This time, it’s Contact Form 7

[code lang=php]
$plugins = array(

//from WordPress plugins repo
array(
'name' => 'Contact Form 7',
'slug' => 'contact-form-7',
'required' => false,
),
);
[/code]

It will show slightly different message this time, as we set the plugin’s required parameter from true to false

If you’re wondering where to get the slug from, it’s actually pretty simple. If the plugin’s url in the WordPress repository is like https://wordpress.org/plugins/contact-form-7/ then the slug is contact-form-7, i.e the last part of it’s url 🙂

Plugin from github repository

If your theme requires a plugin from github, it’s pretty simple to do it using TGM.

[code lang=php]
$plugins = array(

array(
"name"=>"Social Count",
"slug"=>"social-count-plus",
"external_url"=>"https://github.com/claudiosmweb/social-count-plus"
)
);
[/code]

It will show like this

If you click on Begin Installing Plugins then you can see the following screen which will guide you through the next steps!

So the final code block looks like this

[code lang=php]
require_once get_template_directory()."/vendors/tgm/class-tgm-plugin-activation.php";

add_action( 'tgmpa_register', 'theme_slug_register_required_plugins' );

function theme_slug_register_required_plugins() {

$plugins = array(

array(
'name' => 'Visual Composer', // The plugin name.
'slug' => 'js_composer', // The plugin slug (typically the folder name).
'source' => 'js_composer.zip', // The plugin source.
'required' => true, // If false, the plugin is only 'recommended' instead of required.
'force_activation' => false, // If true, plugin is activated upon theme activation and cannot be deactivated until theme switch.
'force_deactivation' => false, // If true, plugin is deactivated upon theme switch, useful for theme-specific plugins.
),

array(
'name' => 'Contact Form 7',
'slug' => 'contact-form-7',
'required' => false,
),
array(
"name"=>"Social Count",
"slug"=>"social-count-plus",
"external_url"=>"https://github.com/claudiosmweb/social-count-plus"
)
);

$config = array(
'id' => 'tgmpa',
'default_path' => get_template_directory()."/plugins/" ,
'menu' => 'tgmpa-install-plugins',
'parent_slug' => 'themes.php',
'capability' => 'edit_theme_options',
'has_notices' => true,
'dismissable' => true,
'dismiss_msg' => '',
'is_automatic' => false,
'message' => '',
);

tgmpa( $plugins, $config );
}

[/code]

I hope you’ve got some idea on how to use this beautiful TGM plugin activation library. Let me know in comments, I’d love to hear your thoughts.