Most of you will have heard about WooCommerce extensions by now, and WooCommerce is great for extending because it has loads of hooks and filters to play with, but in truth, you can extend any WordPress plugin in pretty much any way you want and without touching any of the plugin files.
In this post, you’ll find my personal choice on how to do this, along with some handy hints on getting around the problem of not having the right hook in place.
Understanding plugin extension
I have a template that I call a boilerplate, which I will embed below:
So the first thing to do is change all instances of PB to the name of the plugin you are creating, which, as it is an extension, should probably be the name of the original plugin plus something unique to your extension – possibly what it does.
How do I extend a plugin in WordPress?
If you want to extend a plugin, you’ll use hooks or filters that the plugin developer provides. Here’s a bit about what that means:
Hooks and Filters
Hooks are actions triggered during the execution of the WordPress plugin, and during the use of these hooks, you can add code to change those actions. Hooks are either actions or filters.
- Actions are triggered during the execution of the plugin. The add_action() function attaches your custom function to an action hook.
- Filters let you change data or output generated by the plugin before it’s displayed or processed. The add_filter() function attaches your custom function to a filter hook.
Another way to extend a plugin is by directly modifying its files, but this is much less recommended since it can lead to breaking the functionality of the plugin.
I once built an extension to the Events Manager plugin that allowed the site owner to pay commission to those who posted events – I called it Events Manager Commissions (events-manager-commissions).
In this case, you do a find/replace for PB to Events Manager Commissions, and you are good to go, except for the classname is no good, so it is better to do find replace for PB to Events_Manager_Commissions, and then you only have the Plugin Name (in the top comments) to change from Events_Manager_Commissions to Events Manager Commissions and bobs your uncle.
Potential problems of extending a plugin
Taking on the extension of a plugin is no simple task, and there are several potential issues that can arise in the process. The most threatening are those related to compatibility, security, maintenance overhead, support issues, and performance. Let’s go through these briefly:
- Compatibility:
After modifying a plugin, if it’s updated by its developer, the modifications could stop working or conflict with your version. This could not only cause errors but it could even break your site.
- Security:
Errors in the code could introduce vulnerabilities that hackers exploit to gain access to your site.
- Maintenance overhead:
Once you modify a plugin, you’ll be responsible for maintaining and updating that version, and it can be a lot of work. If you’re modifying several plugins, maintenance can become a chore, taking up time and resources.
- Support:
Once you modify the plugin, its developer can have a hard time providing support or troubleshooting help. If something goes wrong with it, you may be on your own.
- Performance:
Inefficient code in your modification of a plugin can negatively impact the performance of your entire website, causing slow load times, increased server load, and even SEO rankings.
Avoid these issues by following best practices when extending WordPress plugins.
Best practices to consider for plugin extension
To ensure that your modifications will be effective and maintainable, consider putting the following best practices into place:
-
- Use Hooks:
As mentioned earlier, Hooks are the most recommended way to extend plugins on WordPress. This way, your custom code won’t conflict with any core functionality, making it simpler to update the plugin in the future. - Create a Child Theme:
Another thing to consider regarding updates is the creation of a child theme. If your wish is to change the design or layout of a plugin, creating a child theme will ensure that your modifications are kept after updates to your theme. - Use Plugin Boilerplates:
Plugin boilerplates are pre-built frameworks that offer a foundation to create a WordPress plugin. They usually include files and folders following best practices for plugin development, like security, performance, and compatibility with other plugins and WordPress versions. - Document Changes:
As you modify, document the changes so they’re simple to maintain long-term. To make this simple, create a change log or a ReadMe file outlining changes made and reasons for making them.
Test Modifications:
As with making other changes on your site, you should always test your modified plugin first. Ensure that it works as expected and doesn’t create issues related to security or performance. - Update Modifications:
Keep your modifications up to date over time by updating your code to be compatible with new versions of the plugin and of WordPress. This will allow you to take advantage of new features or APIs.
- Use Hooks:
Building a plugin boilerplate
Now, on to the actual meat of the boilerplate. As I said, to extend a WordPress plugin, I like to go for a class-based approach (OOP) because it is easier to store data and pass it around. We already changed the name of our class to Events_Manager_Commissions, so we just need to instantiate it.
Now in some cases, if you rely on other classes you may have to hook into the plugins_loaded hook and instantiate the class there, but in most cases, you can just go ahead and do it either above the class declaration or below. I always go for the above:
global $PB;
$PB = new PB;
This instantiates the class and stores it to global as well. We could do this in one line
$GLOBALS[‘pb’] = new PB;
Now, if we go into the class, we first declare two very important variables we need in the plugin:
private $textdomain = "pb";
private $required_plugins = array();
The first one is the textdomain for i18n translation functions – you can change it to something more in line with the plugin name, or leave it as is. The next one is rather more important because it can literally stop your plugin from being run. You insert into this array the required plugins for this extension. Following the examples, we would make it private
$required_plugins = array(‘events-manager’,’events-manager-pro’);
And then, the first function in the class checks that those plugins are active. See my last post for more on that function. Now on to the main function not only for this class (practically every class, actually) but for my entire method of extending plugins.
function __construct() {
if (!$this->have_required_plugins())
return;
load_plugin_textdomain($this->textdomain, false, dirname(plugin_basename(__FILE__)) . '/languages');
}
So here we call up our check for required plugins and exit (return;) if we don’t have them then we load the plugin textdomain up for the language-related functions. Nothing spectacular there, but this is the main function because it is called automatically when the class is instantiated, and that means we can use it as an easy and central place to connect to any hooks we may need to.
Extending a plugin on your own or with a developer
So you see, that framework gives you a simple and central place from where you can hook into everything and anything you need: multiple plugins, themes, enqueue styles, and scripts, anything all in one place. I am not saying it is perfect, but for me, it allows me to extend wordpress plugins very easily.
So what should you do if you don’t have a hook when you need it? Sure, you can add a hook and contact the plugin devs about adding it to the next release, but more often than not, a workaround can be found.
At the end of the day, of course, you can hire a WordPress developer and avoid potential issues instead.