WordPress provides a collection of core functions called pluggable functions. As the name suggests, we can plug in custom code to these functions to override and enhance their functionality according to our requirements.
The real power of pluggable functions comes with the ability to declare custom functions and make them pluggable for other developers and designers. It's a widely used technique in extending the functionality and features of WordPress Child Themes.
Throughout this article we are going to explore the concept of pluggable functions and their usage.
Using Pluggable Functions in WordPress Core
Pluggable functions in the WordPress core are located in the pluggable.php file inside the wp-includes directory. You can find the complete list of pluggable functions under Pluggable Functions in the WordPress Codex. First I'll show you a list of pluggable functions which can be used in almost every WordPress website.
-
wp_logout
- is used to log the user out of the system. You can do tasks like removing custom session variables and recording the user session time to the database by writing a customwp_logout
function. -
wp_mail
- is the most popular pluggable function of them all. You can modify this function to use a special email template for your emails or any other email sending-related properties. -
wp_new_user_notification
- can be used to customize the format of email sent just after a new user is registered with the system. -
auth_redirect
- is used to redirect a user to the login page if the user is not already logged in. You can use this function to display a message to the user mentioning that the user should be authenticated to access the requested page. -
wp_password_change_notification
- is used to send an email when the password gets changed. You can add additional information to this email using this function.
Now let's see how we can plug a custom function into one of the above functions. I'll use wp_logout
here. First you have to open the pluggable.php file and copy the contents of the wp_logout
function. Then create a new function in your file with the same name and include the code. Following is the default function for wp_logout
:
if ( ! function_exists( 'wp_logout' ) ) { /** * Log the current user out. * * @since 2.5.0 */ function wp_logout() { wp_clear_auth_cookie(); do_action( 'wp_logout' ); } }
Now let's look at the overridden version of the wp_logout
function:
if ( ! function_exists( 'wp_logout' ) ) { /** * Log the current user out. * * @since 2.5.0 */ function wp_logout() { remove_sessions() ; // Custom Function Call wp_clear_auth_cookie(); do_action( 'wp_logout' ); } function remove_sessions() { // Remove custom session and cookie information } }
You can see that I have modified the wp_logout
function in my plugin and added some custom code. This is the process you need to follow in order to override a pluggable function.
The important thing in the above code is the if ( ! function_exists( 'wp_logout' ) ) {
line defined at the top. This line makes your function pluggable by checking whether a function called wp_logout
exists and loads the custom function. Otherwise it will load the default function in pluggable.php.
You might be wondering why the function in the plugin gets called instead of default one even when both functions are prefixed with the function_exists('wp_logout')
condition. That is due to the WordPress action execution order, which I'll be explaining later.
Is It Possible to Skip function_exists
Check for Custom Functions?
Yes it is possible. But you will have issues in the following two scenarios if you omit the check.
- Plugin activation - When you override a pluggable function inside a plugin without the check and try to activate the function, it will generate an error mentioning "Cannot redeclare wp_logout()". If you remove the check after the activation it will work properly.
- Duplicate function in another plugin - There is a possibility that another plugin writer overrides the same function without the condition check. In such cases there will be a conflict since both functions will be in the same name and hence generate an error.
The risk here is that anyone can override your function without your knowledge. I think you should always have the condition check before the function to avoid conflicts.
Now you know how to work with pluggable functions. So let's see where we can place the pluggable functions.
Pluggable Function Execution Process
I have seen a lot of developers including pluggable functions in the functions.php file of a theme and not getting the results they expect. You should have a proper knowledge of WordPress action execution order before creating pluggable functions.
You can find the complete execution procedure under Action Reference in the WordPress Codex. I'll extract the necessary actions for my explanations in the screen below.
The above image shows the general WordPress action execution process. It may vary on the type of functionality used in your plugin and these actions can be called multiple times during a request.
You should clearly see that "must use" plugins are loaded first, followed by active plugins and pluggable functions. Finally the theme is loaded. So according to the process we can make the following conclusions on creating pluggable functions.
- All the custom pluggable functions should be placed inside plugins since plugins are loaded first.
- If plugins do not contain pluggable functions, the default core function will be used.
- You shouldn't be overriding core pluggable functions in your theme files since themes are loaded after pluggable functions. Hence the default function will be used.
Now you know where to put your pluggable functions. Next question will be what happens when two or more plugins override the same core function. It's beyond your control since the first activated plugin will get the preference over others. So if another plugin is activated before your plugin, your pluggable function will not be used.
You can view the active plugin order using the value of the active_plugins
key in the WordPress options table.
Importance of Pluggable Functions
Overriding core pluggable functions allows us to extend the default functionality and hence very useful in certain scenarios. But the real value of pluggable functions comes in when you create your own pluggable functions. These functions will not have any relationship with the core functions.
Generally new pluggable functions are defined in your WordPress themes to extend its functionality and allow child theme developers to override them. So let's see how we can define custom pluggable functions.
Creating Custom Pluggable Functions
First you will have to create the function with an existence check as we did with core functions. The following code shows a sample pluggable function for your theme:
if ( ! function_exists( 'change_header' ) ) { function change_header() { // Code for changing theme header } }
Earlier I mentioned not to create pluggable functions in theme files due to the dependency with default pluggable functions. In this scenario we are creating new pluggable functions and hence there won't be any dependencies. So the action execution process will not have an effect generally.
When to Use Pluggable Functions?
We create child themes to allow developers and designers to extend the design and features of the parent theme without changing the source code of original theme. The basic form of extending can be provided by duplicating the CSS of the parent theme inside the child theme and making necessary customizations.
Apart from CSS styles, themes may contain useful functions such as shortcodes, page templates, and custom filters to provide design elements. As theme developers, we need to provide maximum capabilities for child theme developers. We can effectively use pluggable functions to allow child theme developers to modify these functionalities.
So make sure to convert your existing theme functions to pluggable functions when necessary to allow maximum extendability.
Summary
The WordPress pluggable functions concept allows you to extend the functionality of your themes and plugins. Generally it's preferable to override WordPress core pluggable functions in plugins and your own pluggable functions in themes. Make sure to get a proper understanding of the WordPress action execution sequence before creating pluggable functions to avoid conflicts.
Comments