It’s a common request. You love your WordPress website, the theme is beautiful, and the plugin does almost exactly what you need, but there’s just one thing that you would like to change. You want it to do something differently. How can you modify that WordPress plugin?
Are you sure?
Before you try to modify a plugin, ask yourself if this is really necessary. You might be better off finding a different plugin that already more closely suits your needs. There are so many plugins out there!
Pros: Detailed control over the system’s output and functionality.
Cons: Should only be attempted by advanced users and web development professionals. Subject to a variety of problematic issues. For example, a client invested in a custom extension of a third-party WordPress plugin. At one point, the “parent plugin” author released a major new version that changed core functionality. The client had to weigh the security downside of never updating the parent plugin again, versus the unexpected cost of upgrading the custom extension on fairly short notice. And that was a parent plugin author who was thoughtful enough to “push” a notification to its users before making the big change! Not all plugin authors have considered the possibility that you may have written a custom extension for their plugin, and they may change key features with no notice at any time, potentially rendering your site inoperable if you update the parent plugin without first coding a fix in your custom extension.
So with that said, one possibility is:
Fork the Plugin and Make It Your Own
One alternative to writing a plugin extension is to simply create your own new plugin based on the parent plugin. This way you can eliminate the worry that future updates to the parent plugin might cause problems.
Make a copy of the parent plugin, and rename the folder. Within that folder find the main plugin file, and change the filename to match the new folder name. (For example, you are renaming ‘parent-plugin/parent-plugin.php’ to ‘new-plugin/new-plugin.php.’)
Open up that main plugin file in your code editor, and change the Plugin Name and all that stuff. (You may want to scroll down a bit, to check and make sure you also change the plugin code’s own description of itself.) In order to avoid having your changes overwritten by future updates to the parent plugin, be sure you change the plugin’s name and Plugin URI, and replace them with your own values.
All the plugins in the WordPress repository are GPL licensed, so you can do whatever you want with them. (That said, it is both courteous and customary to retain authorship credit for the people who created and worked on the plugin before you. But feel free to put yourself at the top of the list.)
There is no need to rename all the plugin’s other files at this time. (If you do, you’ll have to also change every corresponding “include” “require” and “enqueue” directive in the plugin… But be warned that a batch rename or string replacement command can complicate matters, for example if the plugin you’re modifying uses variable action hook names; so be sure you know what you’re doing.)
Now you can modify the plugin in any way you like.
Note, the drawback of this method is that you will not receive the benefit of future security patches and other code upgrades to the parent plugin. Best practice would be to monitor the parent plugin repository for changes; and/or to be continuously upgrading your own software: but the reality is, many of the small, lightweight plugins are relatively stable for many years with little or no maintenance.
Extending a Plugin
So you have rejected both the “find a different plugin” option and the “fork it” option. You just want to make a small change; and/or you want to make changes without losing the benefit of future upgrades to the parent plugin. You are determined to write a plugin extension.
Where does the code go?
You can either create your own completely new plugin to extend the parent plugin; or you can include the necessary changes from your active theme’s functions.php file. Customization instructions from parent plugin authors generally recommend the latter, probably because it is much easier to explain. However, as an experienced developer, you can easily create your own “My Custom Plugin Extension” plugin, if you like. My recommendation is to create your own plugin; because separating presentation from functionality is generally considered a WordPress coding best practice.
Is the parent plugin active?
There’s no point in executing a complex code sequence to override a plugin that’s not running. (In certain cases, attempting to do so may cause errors.) Save your site some CPU cycles by first checking, from your constructor or init function:
if(!is_plugin_active('parent-plugin/parent-plugin.php')){return;}
Note, the is_plugin_active() function is not defined when displaying the front-end of your site; and even on the admin side, it’s not defined until later in the loading sequence: so first, you may want to call:
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
Pluggable functions
How you code your plugin extension will depend on the parent plugin’s construction. Some plugins are written with the express intent of making them easily extensible; others, not so much.
Some plugins are written with “pluggable” function definitions. A “pluggable” function simply checks to see if a function has already been defined, before defining it. This allows you to “plug in” your own version of the function definition, in your theme’s functions.php file or in this case in your plugin extension.
If the parent plugin uses pluggable functions, then all you have to do is write your own function definition with the same name as the function you wish to override. (And make sure your function definition loads first.) Done! You have overridden the parent plugin.
Filters
Modern plugins make extensive use of WordPress action hooks and filters. You can leverage these to completely change the output.
For example, the parent plugin’s function call might conclude something like:
return apply_filters(‘filter_name’, $default_value );
Usually there is no filter and the default value is returned. That means you can simply create a function that calls,
add_filter(‘filter_name’, ‘your_override_function’);
Your override function will be passed the default value, and you can modify it in any way you like. (Be sure to return the modified value at the end, obviously.)
If there are already other filters being applied to this value, you want your filter to fire last, so it will override all the others:
add_filter('filter_name', 'your_override_function', $large_integer);
Action Hooks
You are probably familiar with filters and action hooks already. Well-coded parent plugins commonly “hook” their actions to one of the events that occurs during the CMS loading process. To override the parent plugin’s behavior, you can add your own action to the same hook:
add_action('action_hook_name', 'your_override_function', $optional_priority_integer);
where your priority integer will almost always be a higher number than the parent plugin’s action priority, so that your function will be called later.
Alternatively, since these functions often output code to the browser, you can override the parent plugin’s function by first calling:
remove_action('action_hook_name', 'parent_plugin_function', $optional_priority_integer);
and then
add_action('action_hook_name', 'your_override_action_function');
(Remembering, of course, that in order to successfully remove an action, the priority in your remove_action() call must match the priority set by the parent plugin in its add_action() call.)
Removing an action added by an object
It gets a little more complicated if the parent plugin uses object-oriented programming. Then you have to reference either the class name or else the instantiated version of the class, when you call remove_action:
remove_action('action_hook_name', array($parent_plugin_class_or_instantiated_object, 'method_name'), $optional_priority_integer);
Conclusion
If you want to modify a WordPress plugin (and you’ve already checked for alternative plugins but you can’t find one that’s just right) then you can either “fork” the plugin and make a new one; or else you can create a custom plugin extension. Obviously you will want to do this type of work in a development environment, far from a production site where anyone might see the work in progress; and of course, don’t release the code into the wild until you have performed robust testing.
Extending a WordPress plugin can be complicated, but for experienced code developers, it’s generally familiar territory. You can make the changes in your theme’s functions.php file; or you can create your own plugin, to separate functionality from presentation. If the parent plugin uses pluggable functions, you can simply override them by writing your own function definitions with the same name (and be sure your definitions load first). Otherwise, you can override the parent plugin’s functionality by adding an action that fires later in the sequence; by removing the original action altogether; or both!
Good luck, and happy coding!