How to give your plugin pluggable functions

The amazing pluggable machine - photo by lukasWP

Pluggable functions are functions that can be overridden by others.  The key is which is defined first.  So to make one your plugin’s functions pluggable one should define it  as late as possible.  So others can get in first of course, but not so late that your plugin tries to use it before it is defined.

Understanding the sequence of wordpress actions is important.

To make your plugin function pluggable by a theme or another plugin it needs to be defined AFTER the themes and the other plugins. So if your functions are mainly to do with output, you could move them as far back as the ‘wp’ action say.

In your main plugin file:

add_action ('wp','amr_load_pluggables', 10);    //move it later and a low priority

function amr_load_pluggables() {
    require_once('amr-pluggable.php');
}

The Pluggable Functions

Each pluggable function must test that it has not already been defined

if (!function_exists( 'the_pluggable_function')) {
    the_pluggable_function($parameters) {
    // the code
    }
}

The Override Function

The coder doing the overwriting  (ie plugging the pluggable function ) then just defines the function normally in their own plugin, or in their themes functions.php.  All they have to do is not bury it inside an action that executes AFTER the ‘wp’ action (or the action that loads the pluggable files).

Oh and it would be a good idea to fully understand where / when that pluggable function gets called and what it is supposed to do, what values to return etc.  You do not want to cause nasty side effects.  Looking at the code of the pluggable function is a good place to start.

Conditional Override

If they wanted to only override under certain circumstances, EG:  If you want to override ONLY on certain post types and only if certain conditions are met on the single view, then one could do

add_action('wp', 'define_my_override_function', 1) {
// using wp action as well as we need the post query et to have been done already, but a higher priority so will execute before the pluggable function load.
}
function define_my_override_function() {
global $post;
    if (is_single() and ($post->post_type === 'event') and (whatever other criterai)) {
 // then overwrite the pluggable, requires the pluggable loading to be later in the wp action sequence, say on action 'wp' late priority
        function the_pluggable_function($parameters) {
        // your code here
        }
     }
}